Hosting Equipo Avantys 7 min

Git en VPS: Deploy y Control de Versiones

Configura Git en tu VPS para deploys profesionales. Repositorios bare, hooks automáticos, deploy con git push y flujos de trabajo eficientes.

// Compartir

Git en VPS: Deploy y Control de Versiones
Git en VPS - deploy y control de versiones

Subir archivos por FTP es cosa del pasado. Con Git configurado correctamente, despliegas tu código con un simple git push y el servidor se actualiza automáticamente.

Esta guía te enseña a configurar Git para deploys profesionales en tu VPS.

Instalar Git

En el VPS

# Ubuntu/Debian
sudo apt update
sudo apt install git -y

# Verificar
git --version

Configuración inicial

# Configurar identidad
git config --global user.name "Tu Nombre"
git config --global user.email "[email protected]"

# Editor por defecto
git config --global core.editor nano

# Ver configuración
git config --list

Deploy con Git: El flujo

Flujo de deploy con Git

Opciones de deploy

MétodoComplejidadUso
Git pull manualBajaProyectos pequeños
Git bare + hookMediaDeploy automático
GitHub ActionsMedia-AltaCI/CD completo

Método 1: Git pull manual

El más simple. Clonas el repo y haces pull cuando hay cambios.

En el VPS

# Clonar repositorio
cd /var/www
git clone https://github.com/usuario/mi-proyecto.git sitio

# Dar permisos
sudo chown -R www-data:www-data /var/www/sitio

Actualizar

cd /var/www/sitio
git pull origin main

# Si hay dependencias
npm install  # Node.js
composer install  # PHP
pip install -r requirements.txt  # Python

# Reiniciar si es necesario
sudo systemctl restart php8.2-fpm

Script de deploy

#!/bin/bash
# /root/scripts/deploy.sh

cd /var/www/sitio
git pull origin main
npm install --production
npm run build
sudo systemctl restart php8.2-fpm

echo "Deploy completado: $(date)"

Método 2: Git bare + hook (recomendado)

Deploy automático al hacer git push. Sin tocar el servidor manualmente.

Git hooks en VPS

Crear repositorio bare

# Crear directorio para repos
sudo mkdir -p /var/repo
sudo chown -R $USER:$USER /var/repo

# Crear repo bare
cd /var/repo
git init --bare mi-proyecto.git

Crear hook post-receive

nano /var/repo/mi-proyecto.git/hooks/post-receive
#!/bin/bash
TARGET="/var/www/mi-proyecto"
GIT_DIR="/var/repo/mi-proyecto.git"
BRANCH="main"

while read oldrev newrev ref
do
    if [ "$ref" = "refs/heads/$BRANCH" ]; then
        echo "Desplegando rama $BRANCH..."
        
        # Checkout al directorio web
        git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
        
        # Permisos
        chown -R www-data:www-data $TARGET
        
        # Comandos post-deploy
        cd $TARGET
        
        # Para Node.js
        if [ -f "package.json" ]; then
            npm install --production
            npm run build 2>/dev/null || true
        fi
        
        # Para PHP/Composer
        if [ -f "composer.json" ]; then
            composer install --no-dev --optimize-autoloader
        fi
        
        # Limpiar caché
        # wp cache flush --path=$TARGET 2>/dev/null || true
        
        echo "Deploy completado: $(date)"
    fi
done
# Hacer ejecutable
chmod +x /var/repo/mi-proyecto.git/hooks/post-receive

Crear directorio destino

sudo mkdir -p /var/www/mi-proyecto
sudo chown -R www-data:www-data /var/www/mi-proyecto

Configurar en tu máquina local

# En tu proyecto local
cd mi-proyecto

# Añadir remote del VPS
git remote add production usuario@tu-vps:/var/repo/mi-proyecto.git

# Ver remotes
git remote -v

Desplegar

# Push a producción
git push production main

# Verás la salida del hook en tu terminal

Deploy con clave SSH

Generar clave (si no tienes)

# En tu máquina local
ssh-keygen -t ed25519 -C "deploy-key"

Añadir al VPS

# Copiar clave pública al VPS
ssh-copy-id -i ~/.ssh/id_ed25519.pub usuario@tu-vps

# O manualmente
cat ~/.ssh/id_ed25519.pub
# Pegar en ~/.ssh/authorized_keys del VPS

Configurar SSH config

# ~/.ssh/config
Host mi-vps
    HostName tu-vps.com
    User usuario
    IdentityFile ~/.ssh/id_ed25519
# Ahora puedes usar
git remote add production mi-vps:/var/repo/mi-proyecto.git

Hooks útiles

Hook con notificación Slack

#!/bin/bash
# post-receive con Slack

TARGET="/var/www/mi-proyecto"
GIT_DIR="/var/repo/mi-proyecto.git"
SLACK_WEBHOOK="https://hooks.slack.com/services/xxx"

while read oldrev newrev ref
do
    BRANCH=$(echo $ref | cut -d/ -f3)
    
    if [ "$BRANCH" = "main" ]; then
        # Deploy
        git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f main
        
        # Obtener info del commit
        COMMIT=$(git --git-dir=$GIT_DIR log -1 --pretty=format:"%h - %s (%an)")
        
        # Notificar a Slack
        curl -X POST -H 'Content-type: application/json' \
            --data "{\"text\":\"🚀 Deploy completado: $COMMIT\"}" \
            $SLACK_WEBHOOK
        
        echo "Deploy completado: $COMMIT"
    fi
done

Hook con rollback automático

#!/bin/bash
# post-receive con rollback

TARGET="/var/www/mi-proyecto"
GIT_DIR="/var/repo/mi-proyecto.git"
HEALTH_URL="http://localhost/health"

while read oldrev newrev ref
do
    if [ "$ref" = "refs/heads/main" ]; then
        # Guardar commit anterior
        PREV_COMMIT=$oldrev
        
        # Deploy
        git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f main
        
        cd $TARGET
        npm install --production
        npm run build
        
        # Verificar health
        sleep 5
        if ! curl -sf $HEALTH_URL > /dev/null; then
            echo "ERROR: Health check falló. Haciendo rollback..."
            git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $PREV_COMMIT
            npm install --production
            npm run build
            echo "Rollback completado a $PREV_COMMIT"
            exit 1
        fi
        
        echo "Deploy exitoso: $newrev"
    fi
done

Hook para WordPress

#!/bin/bash
# post-receive para WordPress (solo tema)

TARGET="/var/www/wordpress/wp-content/themes/mi-tema"
GIT_DIR="/var/repo/mi-tema.git"

while read oldrev newrev ref
do
    if [ "$ref" = "refs/heads/main" ]; then
        git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f main
        
        cd $TARGET
        
        # Instalar dependencias del tema
        if [ -f "package.json" ]; then
            npm install
            npm run build
        fi
        
        # Permisos
        chown -R www-data:www-data $TARGET
        
        # Limpiar caché de WordPress
        wp cache flush --path=/var/www/wordpress --allow-root 2>/dev/null
        
        echo "Tema desplegado: $(date)"
    fi
done

Deploy desde GitHub/GitLab

Con deploy key

# En el VPS, generar clave
ssh-keygen -t ed25519 -C "vps-deploy-key" -f ~/.ssh/deploy_key

# Ver clave pública
cat ~/.ssh/deploy_key.pub

# Añadir en GitHub: Settings → Deploy keys → Add

Clonar con deploy key

# Configurar SSH
nano ~/.ssh/config
Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/deploy_key
# Clonar
git clone [email protected]:usuario/repo.git /var/www/sitio

Script de deploy desde GitHub

#!/bin/bash
# /root/scripts/deploy-from-github.sh

REPO_DIR="/var/www/mi-proyecto"
BRANCH="main"

cd $REPO_DIR

# Fetch cambios
git fetch origin

# Verificar si hay cambios
LOCAL=$(git rev-parse HEAD)
REMOTE=$(git rev-parse origin/$BRANCH)

if [ "$LOCAL" = "$REMOTE" ]; then
    echo "Ya está actualizado"
    exit 0
fi

# Hacer pull
git pull origin $BRANCH

# Post-deploy
npm install --production
npm run build

echo "Actualizado de $LOCAL a $REMOTE"

Múltiples entornos

Estructura de branches

main        → Producción
staging     → Pre-producción
develop     → Desarrollo

Múltiples remotes

# En tu máquina local
git remote add production usuario@vps-prod:/var/repo/proyecto.git
git remote add staging usuario@vps-staging:/var/repo/proyecto.git

# Deploy a staging
git push staging develop:main

# Deploy a producción
git push production main

Hook multi-branch

#!/bin/bash
# post-receive multi-entorno

while read oldrev newrev ref
do
    BRANCH=$(echo $ref | cut -d/ -f3)
    
    case $BRANCH in
        main)
            TARGET="/var/www/produccion"
            ;;
        staging)
            TARGET="/var/www/staging"
            ;;
        *)
            echo "Branch $BRANCH ignorada"
            continue
            ;;
    esac
    
    echo "Desplegando $BRANCH en $TARGET..."
    git --work-tree=$TARGET --git-dir=$GIT_DIR checkout -f $BRANCH
    
    cd $TARGET
    npm install --production
    npm run build
    
    echo "Deploy $BRANCH completado"
done

Comandos útiles

En el VPS

# Ver último commit desplegado
cd /var/www/sitio
git log -1 --oneline

# Ver cambios pendientes (si editaste en servidor)
git status
git diff

# Descartar cambios locales
git checkout -- .
git clean -fd

# Forzar sync con remote
git fetch origin
git reset --hard origin/main

Debugging de hooks

# Ver log del hook
# Los hooks escriben a stdout, visible en el git push

# Probar hook manualmente
cd /var/repo/mi-proyecto.git
echo "oldrev newrev refs/heads/main" | ./hooks/post-receive

# Ver errores
tail -f /var/log/syslog | grep git

Seguridad

Proteger el repo bare

# Solo acceso SSH, no HTTP
# Firewall
sudo ufw deny 9418  # Puerto git

# Permisos restrictivos
chmod 700 /var/repo
chmod 700 /var/repo/mi-proyecto.git

Usuario dedicado para deploy

# Crear usuario
sudo adduser --disabled-password deploy

# Añadir a www-data
sudo usermod -aG www-data deploy

# Configurar sudo limitado
sudo visudo
# deploy ALL=(www-data) NOPASSWD: ALL

Preguntas frecuentes

¿Git bare o git clone normal en el servidor?

Git bare para recibir pushes y desplegar con hooks. Git clone normal si solo haces pull manualmente. El método bare + hook es más profesional y automatizado.

¿Por qué mi hook no se ejecuta?

Verifica que el hook es ejecutable (chmod +x). También revisa que el nombre sea exacto (post-receive, sin extensión). Los errores de sintaxis también pueden impedirlo.

¿Puedo usar Git con WordPress?

Sí, pero normalmente solo para el tema o plugins custom. No incluyas wp-content/uploads ni wp-config.php en el repo. Usa .gitignore adecuado.

¿Git o GitHub Actions para deploy?

Git bare + hooks es más simple y directo. GitHub Actions es mejor si necesitas tests, builds complejos, o despliegues condicionales. Puedes combinar ambos.

¿Cómo hago rollback a una versión anterior?

En el servidor: git checkout COMMIT_HASH. O implementa rollback en tu hook guardando el commit anterior y revirtiendo si el health check falla.

Nuestra recomendación

Setup básico:

  1. Repositorio bare en /var/repo
  2. Hook post-receive con deploy automático
  3. Remote “production” en tu máquina local
  4. Deploy con git push production main

Para equipos:

  • Múltiples entornos (staging, producción)
  • Hooks con notificaciones
  • Rollback automático
  • Usuario deploy dedicado

¿Necesitas CI/CD gestionado? La administración gestionada de Avantys incluye configuración de pipelines de deploy.


Conclusión

Git transforma los deploys de una tarea manual y propensa a errores en un proceso automatizado y confiable. Con un hook bien configurado, despliegas con un comando y tienes rollback si algo falla.

Empieza con el método bare + hook y evoluciona según necesites.

¿Necesitas un VPS para tus proyectos? Explora los VPS de Avantys con Git preconfigurado.


¿Quieres que lo hagamos por ti?

En Avantys gestionamos tu web, hosting y crecimiento digital de punta a punta. Tú a lo importante.

Hablar con Avantys
// Boletín

Suscríbete al boletín

Guías nuevas, sin spam. Cancela cuando quieras.