Contexto técnico
Para iniciar GitLab Runner, se utiliza la imagen oficial gitlab/gitlab-runner:latest. Una vez que el Runner se ejecuta como contenedor y se registra en el servidor de GitLab, está listo para procesar los trabajos definidos en los pipelines.
Cada trabajo inicia un contenedor temporal donde se ejecutan comandos como dotnet build, dotnet pack o docker build. Este contenedor se destruye automáticamente al finalizar el trabajo. La imagen que crearemos aquí es precisamente para estos contenedores temporales.
Preparación del entorno de construcción
Cree un directorio vacío para la construcción de la imagen. Este directorio contendrá tres archivos esenciales: un Dockerfile sin extensión y dos scripts shell que integran un sistema centralizado de definición de versiones para facilitar la configuración en .gitlab-ci.yml.
1. Dockerfile
FROM ubuntu:20.04
RUN apt-get update && apt-get install -y \
libcurl4 \
wget \
apt-utils \
net-tools \
bind9-utils \
vim \
iputils-ping \
apt-transport-https \
docker.io
RUN ln -s /lib/x86_64-linux-gnu/libdl-2.24.so /lib/x86_64-linux-gnu/libdl.so
RUN wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
&& dpkg -i packages-microsoft-prod.deb \
&& rm packages-microsoft-prod.deb
RUN apt-get update && apt-get install -y \
dotnet-sdk-5.0 \
dotnet-sdk-6.0 \
dotnet-sdk-7.0 \
dotnet-sdk-8.0
RUN mkdir -p /root/.ssh && chmod 700 /root/.ssh
RUN mkdir -p /home/public
COPY fetch-version-files.sh /home/public/
COPY update-remote-version.sh /home/public/
COPY deploy-container.sh /home/public/
RUN chmod +x /home/public/*.sh
COPY --from=docker/buildx-bin /buildx /usr/libexec/docker/cli-plugins/docker-buildx
2. fetch-version-files.sh
Este script descarga archivos de configuración de versiones desde un servidor HTTP.
Parámetros: URL base del servidor HTTP (ejemplo: http://dev.ejemplo.com).
Función: elimina archivos Directory.*.props y urls.txt del directorio actual, luego descarga urls.txt y los archivos listados en él desde el servidor.
#!/bin/bash
set -e
base_url="$1"
urls_file="urls.txt"
echo "Limpiando archivos previos..."
rm -f Directory.*.props
rm -f "$urls_file"
echo "Descargando lista de URLs desde $base_url/$urls_file"
wget -q "$base_url/$urls_file"
if [[ ! -f "$urls_file" ]]; then
echo "Error: $urls_file no encontrado."
exit 1
fi
echo "Descargando archivos de versiones..."
while IFS= read -r url; do
clean_url=$(echo "$url" | tr -d '\r')
[[ -n "$clean_url" ]] && wget -q -x -nH "$clean_url" --content-disposition
done < "$urls_file"
3. update-remote-version.sh
Este script actualiza números de versión en un serivdor remoto vía SSH.
Parámetros:
1. Nombre de usuario Linux para SSH
2. Dirección del servidor HTTP (nombre o IP)
3. Nombre del directorio raíz del sitio web (sin prefijo /www/wwwroot/)
4. Nombre del archivo de versiones (dentro del subdirectorio version-numbers)
5. Nuevo valor de versión
#!/bin/bash
user="$1"
server="$2"
web_root="$3"
version_file="$4"
new_version="$5"
echo "Copiando claves SSH..."
cp /deploy/ssh/* /root/.ssh/ 2>/dev/null || true
echo "Conectando a $user@$server..."
ssh "$user@$server" << EOF
cd "/www/wwwroot/$web_root/version-numbers"
sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+/$new_version/g' "$version_file"
EOF
4. deploy-container.sh
Este script despliega contenedores Docker en servidores remotos vía SSH.
Parámetros:
1. Nombre del contenedor
2. Puerto expuesto en el host
3. Puerto del contenedor
4. Imagen de Docker a desplegar
5. Entorno ASP.NET Core (ASPNETCORE_ENVIRONMENT)
6. Dominio del registro de Docker
7. Usuario del registro de Docker
8. Contraseña del registro de Docker
9. Usuario para SSH en el servidor de despliegue
10. Dirección del servidor de despliegue
#!/bin/bash
container_name="$1"
host_port="$2"
container_port="$3"
image="$4"
aspnet_env="$5"
registry_domain="$6"
registry_user="$7"
registry_pass="$8"
deploy_user="$9"
deploy_server="${10}"
echo "Desplegando $image como $container_name en $deploy_server..."
ssh "$deploy_user@$deploy_server" << EOF
# Detener y eliminar contenedor existente
if docker ps -a --format '{{.Names}}' | grep -q "^$container_name\$"; then
docker stop "$container_name"
docker rm "$container_name"
fi
# Iniciar nuevo contenedor
docker run -d --restart=always \
--name "$container_name" \
-p "$host_port:$container_port" \
-e "ASPNETCORE_ENVIRONMENT=$aspnet_env" \
-v /mnt/config:/var/config \
"$image"
EOF
Construcción y distribución de la imagen
Con los archivos preparados, el directorio debe contener: Dockerfile, fetch-version-files.sh, update-remote-version.sh y deploy-container.sh.
Construcción de la imagen
docker build -t registry.ejemplo.com/imagenes/gitlab-runner-dotnet:latest .
Publicación en el registro
docker push registry.ejemplo.com/imagenes/gitlab-runner-dotnet:latest
Si aún no ha iniciado sesión en el registro, ejecute docker login previamente.