Tutorial

Instalar GitLab CE en un VPS: guía completa

Despliegue17 min de lectura9 pasos

GitHub y Bitbucket alojan sus repositorios, pero imponen sus reglas: minutos de CI racionados, propiedad del código incierta, precios que suben con el tamaño del equipo. GitLab CE (Community Edition, licencia MIT/EE Core) reúne en un solo servidor una forja git completa, un motor de CI/CD sin límite de minutos, un registry Docker privado y wikis — sin suscripción SaaS. Esta guía le muestra cómo instalarlo en menos de treinta minutos en un VPS con Docker Compose, configurar el SMTP, conectar un runner y evitar los errores clásicos: GITLAB_OMNIBUS_CONFIG mal configurado, SSL que caduca por no haber activado ACME, runner sin registrar.

Contenido· Por qué GitLab CE en lugar de GitHub o Bitbucket1/12
  1. 01Por qué GitLab CE en lugar de GitHub o Bitbucket
  2. 02Lo que GitLab CE incluye de entrada
  3. 03Requisitos previos: lo que hace falta antes de empezar
  4. 04De la instalación a su primer proyecto
  5. 05Configurar el runner Docker y escribir su primer pipeline CI/CD
  6. 06Configuración detallada del SMTP
  7. 07Copia de seguridad y restauración de GitLab
  8. 08Resolución de problemas: las tres averías más frecuentes
  9. 09Diagnóstico avanzado: Sidekiq bloqueado, timeout de Puma y OOM en Gitaly
  10. 10Optimizar la RAM: swap y workers de Puma
  11. 11GitLab CE, Forgejo o Gitea: cómo elegir
  12. 12Cuándo elegir GitLab CE y cuándo elegir Forgejo

Por qué GitLab CE en lugar de GitHub o Bitbucket

GitHub y Bitbucket son servicios gestionados: prácticos al principio, pero su modelo de precios evoluciona con el tamaño del equipo, los minutos de CI están contados en los planes gratuitos y su código se aloja en una infraestructura de terceros. GitLab CE invierte esa ecuación: usted despliega la forja en su VPS, conserva el control total del código y de los datos, y la CI/CD va incluida sin cuota de minutos impuesta por un tercero. Para una agencia o un equipo de desarrolladores que factura a clientes o trata datos sensibles, ese control suele ser innegociable. GitLab CE es hoy una de las forjas git más desplegadas en self-hosted: su base de código es pública, su núcleo es libre y sus diez años de existencia le han dado una comunidad de colaboradores activa.

Lo que GitLab CE incluye de entrada

  • Forja git completa: repositorios privados y públicos, merge requests, revisión de código, protección de ramas y CODEOWNERS.
  • CI/CD integrada sin límite de minutos impuesto: pipelines YAML (.gitlab-ci.yml), environments, deploy tokens y artifacts.
  • Registry Docker privado alojado en su dominio: docker pull git.yourdomain.com/group/image:tag sin cuenta de Docker Hub.
  • Wikis y páginas por proyecto y por grupo, con renderizado Markdown completo.
  • Gestión de issues y milestones: tablero kanban, etiquetas, iteraciones y burndown chart incluidos.
  • Runners en paralelo: registre tantos runners como quiera en su infraestructura o en sus CI workers.
  • Webhooks para avisar a una herramienta externa (Slack, PagerDuty, su servidor de despliegue) en cada push o merge.
  • RBAC granular con cinco niveles de acceso (Guest, Reporter, Developer, Maintainer, Owner) y soporte opcional de LDAP/SAML.

Requisitos previos: lo que hace falta antes de empezar

GitLab CE consume mucha memoria — es uno de sus inconvenientes más citados frente a Forgejo o Gitea. Prevea 4 GB de RAM como mínimo para un uso ligero (menos de diez usuarios activos); se recomiendan 8 GB en cuanto añada runners en la misma máquina o active el registry Docker. Por debajo de 4 GB, Puma y Sidekiq compiten por la memoria y GitLab responde con 502 bajo carga. En disco, cuente al menos 20 GB para la instalación y los repositorios iniciales — prevea 50 GB si piensa guardar imágenes Docker en el registry. También necesita: un nombre de dominio apuntando a la IP del VPS, los puertos 80, 443 y 22 abiertos en su cortafuegos, y Docker Engine con el plugin Compose v2 instalados.

De la instalación a su primer proyecto

  1. Crear el árbol de carpetas

    Cree una carpeta dedicada y los tres volúmenes persistentes que utiliza GitLab: mkdir -p /opt/gitlab/{config,logs,data}. Sin ellas, la configuración y los repositorios desaparecen en cada docker compose down.

  2. Escribir el fichero docker-compose.yml

    Cree /opt/gitlab/docker-compose.yml. La clave GITLAB_OMNIBUS_CONFIG concentra toda la configuración específica de su instancia — sustituya git.yourdomain.com por su dominio real. Defina el servicio gitlab con la imagen gitlab/gitlab-ce:17.2.1-ce.0, restart: unless-stopped, puertos 80, 443 y 22, volúmenes, shm_size: 256m y env_file: .env.

  3. Rellenar GITLAB_OMNIBUS_CONFIG

    En GITLAB_OMNIBUS_CONFIG, defina como mínimo: external_url 'https://git.yourdomain.com'; letsencrypt['enable'] = true; parámetros SMTP — gitlab_rails['smtp_enable'] = true, dirección, puerto 587, usuario, contraseña desde ENV, autenticación login, smtp_enable_starttls_auto = true. Todas las líneas deben estar dentro del bloque GITLAB_OMNIBUS_CONFIG.

  4. Crear el fichero .env para los secretos

    Cree /opt/gitlab/.env y restrinja sus permisos: touch /opt/gitlab/.env && chmod 600 /opt/gitlab/.env. Añada GITLAB_SMTP_PASSWORD=su_contraseña_smtp. Añada .env a su .gitignore.

  5. Arrancar GitLab y esperar a la inicialización

    Lance la stack: docker compose -f /opt/gitlab/docker-compose.yml up -d. Espere unos 5 minutos antes de acceder a la interfaz web. Siga el avance con docker compose -f /opt/gitlab/docker-compose.yml logs -f gitlab y espere el mensaje gitlab Reconfigured!.

  6. Recuperar la contraseña root inicial

    Recupérela con: docker exec -it gitlab-gitlab-1 grep 'Password:' /etc/gitlab/initial_root_password. Este fichero se elimina automáticamente 24 horas después — anote la contraseña de inmediato.

  7. Conectarse, cambiar la contraseña y desactivar el registro abierto

    Abra https://git.yourdomain.com. Conéctese con root. Cambie la contraseña en User Settings → Password. Desactive el registro público en Admin Area → Settings → General → Sign-up restrictions.

  8. Registrar un GitLab Runner

    Instale gitlab-runner y recupere el token de registro en Admin Area → Runners. Registre: gitlab-runner register --url https://git.yourdomain.com --registration-token VOTRE_TOKEN --executor docker --docker-image alpine:latest.

  9. Comprobar el envío de correos

    Pruebe desde la consola Rails: docker exec -it gitlab-gitlab-1 gitlab-rails console y luego Notify.test_email('[email protected]', 'Test GitLab', 'Bonjour').deliver_now.

Copias de seguridad automáticas. GitLab incluye un comando de copia de seguridad completa: docker exec -t gitlab-gitlab-1 gitlab-backup create. Prográmelo en crontab -e con 0 3 * * * docker exec -t gitlab-gitlab-1 gitlab-backup create CRON=1. Sincronice la carpeta de archivos con un almacenamiento externo (S3, rclone) — una copia local no es una copia de seguridad.

Configurar el runner Docker y escribir su primer pipeline CI/CD

El executor Docker es el más recomendado: cada job corre en un contenedor aislado. Tras registrar el runner, su fichero /etc/gitlab-runner/config.toml contiene un bloque [runners.docker]. Añada volumes = ["/cache"] y pull_policy = ["if-not-present"] para acelerar los builds.

Ejemplo de pipeline básico en .gitlab-ci.yml:

stages:
  - test
  - build
  - deploy

variables:
  DOCKER_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

test:unit:
  stage: test
  image: node:20-alpine
  cache:
    key: $CI_COMMIT_REF_SLUG
    paths:
      - node_modules/
  script:
    - npm ci
    - npm test
  only:
    - merge_requests
    - main

build:image:
  stage: build
  image: docker:26
  services:
    - docker:26-dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $DOCKER_IMAGE .
    - docker push $DOCKER_IMAGE
  only:
    - main

deploy:prod:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache openssh-client
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | ssh-add -
  script:
    - ssh -o StrictHostKeyChecking=no [email protected] "docker pull $DOCKER_IMAGE && docker compose up -d"
  only:
    - main
  when: manual

Las variables CI_REGISTRY_USER, CI_REGISTRY_PASSWORD y CI_REGISTRY se inyectan automáticamente por GitLab CE. La variable SSH_PRIVATE_KEY se define en Settings → CI/CD → Variables marcada como Masked. El job deploy:prod tiene when: manual — no se dispara automáticamente.

Configuración detallada del SMTP

GitLab envía correos en cada merge request, mención, pipeline completado o alerta de seguridad. Una configuración SMTP ausente o errónea corta silenciosamente esas notificaciones.

Bloque completo en GITLAB_OMNIBUS_CONFIG para un relay SMTP autenticado (STARTTLS, puerto 587):

gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = 'smtp.yourdomain.com'
gitlab_rails['smtp_port'] = 587
gitlab_rails['smtp_user_name'] = '[email protected]'
gitlab_rails['smtp_password'] = ENV['GITLAB_SMTP_PASSWORD']
gitlab_rails['smtp_authentication'] = 'login'
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['gitlab_email_from'] = '[email protected]'
gitlab_rails['gitlab_email_reply_to'] = '[email protected]'

Para TLS directo (puerto 465), sustituya smtp_enable_starttls_auto = true por smtp_tls = true. Las claves fuera del bloque omnibus se ignoran en silencio — pruebe siempre con Notify.test_email(…).deliver_now desde la consola Rails.

Copia de seguridad y restauración de GitLab

El comando docker exec -t gitlab-gitlab-1 gitlab-backup create genera un tar completo con repositorios, base de datos PostgreSQL y artifacts. Importante: no incluye /etc/gitlab/gitlab.rb ni /etc/gitlab/gitlab-secrets.json — guárdelos por separado:

tar czf /opt/gitlab/config-secrets-$(date +%Y%m%d).tar.gz \
  /opt/gitlab/config/gitlab.rb \
  /opt/gitlab/config/gitlab-secrets.json

Restauración en tres pasos: instale la misma versión menor que produjo la copia; copie el tar en /opt/gitlab/data/backups/; luego:

docker exec -it gitlab-gitlab-1 gitlab-ctl stop puma
docker exec -it gitlab-gitlab-1 gitlab-ctl stop sidekiq
docker exec -it gitlab-gitlab-1 gitlab-backup restore BACKUP=<timestamp>_<version>
docker exec -it gitlab-gitlab-1 gitlab-ctl restart
docker exec -it gitlab-gitlab-1 gitlab-rake gitlab:check SANITIZE=true

Planifique la copia a las 3 de la madrugada y sincronice a almacenamiento externo.

Resolución de problemas: las tres averías más frecuentes

502 Bad Gateway al arrancar. GitLab tarda unos 5 minutos en estar plenamente operativo. Si el 502 persiste, compruebe que Puma ha arrancado: docker exec gitlab-gitlab-1 gitlab-ctl status puma. La falta de RAM es la causa más frecuente. El SMTP no funciona. Verifique que el bloque gitlab_rails['smtp_*'] esté dentro de GITLAB_OMNIBUS_CONFIG — una clave fuera del bloque es un fallo silencioso. Runner no conectado. Compruebe con gitlab-runner verify --url https://git.yourdomain.com. Un certificado TLS autofirmado o un DNS no resoluble desde la máquina del runner son las causas habituales.

Diagnóstico avanzado: Sidekiq bloqueado, timeout de Puma y OOM en Gitaly

Sidekiq queue stuck. Compruebe el estado:

docker exec gitlab-gitlab-1 gitlab-ctl status sidekiq
docker exec gitlab-gitlab-1 gitlab-rake gitlab:sidekiq:check

Para vaciar una cola sin reiniciar: docker exec -it gitlab-gitlab-1 gitlab-rails console -e production luego Sidekiq::Queue.new('mailers').clear. Para reiniciarlo sin perder jobs pendientes: docker exec gitlab-gitlab-1 gitlab-ctl restart sidekiq.

Timeout de Puma. Añada en GITLAB_OMNIBUS_CONFIG: puma['worker_timeout'] = 90 (predeterminado 60 s). Si persisten los timeouts, la causa casi siempre es falta de RAM o un número de workers inadecuado.

OOM en Gitaly. Verifique con dmesg | grep -i kill. Reduzca la caché: gitaly['configuration']['git']['catfile_cache_size'] = 5 (predeterminado 100).

Contenedor que sale al arrancar. Revise los logs: docker compose logs gitlab | tail -50. Causas frecuentes: conflicto en el puerto 22, volumen no escribible o sintaxis Ruby inválida en GITLAB_OMNIBUS_CONFIG.

Optimizar la RAM: swap y workers de Puma

Reducir workers de Puma. En GITLAB_OMNIBUS_CONFIG:

puma['worker_processes'] = 2
puma['min_threads'] = 1
puma['max_threads'] = 4

Cada worker Puma consume entre 200 y 300 MB. Dos workers son suficientes para menos de quince usuarios activos simultáneos.

Añadir swap. En un VPS sin swap preconfigurado:

fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab

Recomendaciones de RAM y CPU por tamaño de equipo

| Tamaño del equipo | RAM recomendada | vCPU | Notas |
|---|---|---|---|
| 1–5 desarrolladores | 4 GB | 2 | Runners en la misma máquina posibles con swap |
| 5–15 desarrolladores | 8 GB | 4 | Runner dedicado aconsejable a partir de 8+ pipelines/día |
| 15–30 desarrolladores | 16 GB | 8 | Registry Docker activo, Gitaly bajo carga |
| 30+ desarrolladores | 32 GB+ | 16+ | Separar Gitaly y Sidekiq en máquinas dedicadas |

GitLab CE, Forgejo o Gitea: cómo elegir

Desplace la tabla

CriterioGitLab CEForgejo / Gitea
LicenciaMIT / EE CoreMIT
RAM en reposo300–600 MB (Puma + Sidekiq)30–50 MB
CI/CD nativaSí (`.gitlab-ci.yml`, runners)Forgejo: sí mediante Woodpecker CI; Gitea: no nativa
Registry Docker integradoForgejo: sí; Gitea: no nativo
Wikis por proyecto
LDAP / SAMLSí (CE)Forgejo: sí; Gitea: LDAP sí, SAML no
Curva de aprendizajeAlta (interfaz rica)De baja a media
Ideal paraEquipos de 5+ con CI, registry y RBACEquipos ligeros, forja simple, poca huella de RAM

Cuándo elegir GitLab CE y cuándo elegir Forgejo

GitLab CE es la elección correcta si su equipo necesita una CI/CD robusta directamente integrada en la forja, un registry Docker privado en su dominio, pipelines de despliegue con environments y deploy tokens, o una gestión de proyecto con issues, milestones y kanban sin herramienta externa. Su huella de memoria (4–8 GB) es el precio de esa riqueza funcional. Forgejo o Gitea se imponen cuando la memoria es la restricción principal, cuando la forja es la única necesidad (sin CI integrada). En un VPS de 2 GB, GitLab CE no es viable; Forgejo funciona con 256 MB. En un VPS de 8 GB dedicado a un equipo de desarrolladores, GitLab CE ofrece un entorno completo equivalente al que GitHub pone en su plataforma SaaS — bajo su control y sin suscripción mensual por usuario.

Un VPS listo para GitLab CE

GitLab CE necesita un VPS de 4 a 8 GB de RAM, un disco generoso y una IP dedicada. Nuestros VPS ServOrbit se entregan con el sistema que elija entre Ubuntu 24.04 LTS, Ubuntu 22.04 LTS, Debian 12 y AlmaLinux 9 y acceso root inmediato — suficiente para tener su forja en línea en treinta minutos.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva