¿Dónde se ejecuta realmente el despliegue?
Exactamente! Has dado en el clavo. No, no necesitas tener Git instalado dentro del contenedor. De hecho, no deberías tenerlo.
Vamos a desglosarlo para que quede completamente claro y veas por qué es así.
¿Dónde se ejecuta realmente el despliegue?
Cuando hablamos de "subir tu aplicación por Git" (en lugar de FTP), el proceso NO ocurre dentro del contenedor de tu aplicación (PHP-FPM). Ocurre en el servidor anfitrión (host) o en un servidor de despliegue separado.
Escenario típico de despliegue con Git
Imagina que tienes un servidor en la nube (DigitalOcean, AWS, etc.) con esta estructura:
Servidor de Producción
├── Host (Sistema Operativo: Linux)
│ ├── Git (¡Instalado aquí!)
│ ├── Código de la aplicación (en /var/www/mi-app)
│ ├── Docker
│ │ ├── Contenedor PHP-FPM (NO tiene Git)
│ │ ├── Contenedor Nginx (NO tiene Git)
│ │ └── Contenedor MySQL (NO tiene Git)
│ └── Scripts de despliegue
└── (Usuarios finales acceden vía HTTP)¿Cómo funciona el despliegue con Git en este escenario?
Haces
git pushdesde tu computadora local a GitHub (o GitLab, Bitbucket).El servidor de producción (el host) tiene Git instalado y detecta el nuevo commit.
El servidor ejecuta
git pullen el host, no en el contenedor. Los archivos se actualizan en/var/www/mi-app.El servidor ejecuta comandos de construcción y actualización en el host:
# En el host, NO dentro del contenedor docker compose exec app composer install # Actualiza dependencias dentro del contenedor docker compose exec app php artisan migrate # Ejecuta migraciones dentro del contenedor docker compose restart # Reinicia servicios si es necesarioGracias a los volúmenes, los archivos actualizados en el host (
/var/www/mi-app) se montan automáticamente dentro del contenedor (en/var/www/html). El contenedor ahora ejecuta la nueva versión sin necesidad de saber que existe Git.
¿Por qué no instalar Git en el contenedor?
| Razón | Explicación |
|---|---|
| Responsabilidad única | Un contenedor debe hacer una sola cosa: ejecutar tu aplicación PHP. Git es una herramienta de control de versiones, no un runtime de aplicación. |
| Tamaño y complejidad | Instalar Git añade peso innecesario a tu imagen Docker. |
| Seguridad | El contenedor no necesita credenciales, claves SSH o acceso a tu repositorio remoto. Si el contenedor es comprometido, no tendrá acceso a tu código fuente en GitHub. |
| Persistencia | Los contenedores son efímeros (se crean y destruyen constantemente). Un docker compose down -v eliminaría cualquier cambio hecho dentro del contenedor. |
| Flujo de trabajo correcto | git pull descarga archivos. Si lo ejecutas dentro del contenedor, esos archivos se escribirían en el sistema de archivos del contenedor, que es volátil y no se sincroniza correctamente con el host. |
El ejemplo correcto: Despliegue con Git (sin FTP)
Herramienta: Deployer (PHP)
# 1. En tu computadora local, haces push a GitHub
git push origin main
# 2. En tu servidor (host), ejecutas el script de despliegue
# (Esto se puede automatizar con GitHub Actions, GitLab CI, etc.)Script de despliegue simple (en el host):
#!/bin/bash
# deploy.sh - Se ejecuta en el HOST, no en el contenedor
# 1. Actualizar código desde GitHub (Git está en el host)
cd /var/www/mi-app
git pull origin main
# 2. Instalar dependencias dentro del contenedor
docker compose exec app composer install --no-dev --optimize-autoloader
# 3. Ejecutar migraciones dentro del contenedor
docker compose exec app php artisan migrate --force
# 4. Limpiar caché dentro del contenedor
docker compose exec app php artisan config:cache
docker compose exec app php artisan route:cache
docker compose exec app php artisan view:cache
# 5. Reiniciar servicios (opcional)
docker compose restart
echo "¡Despliegue completado!"Herramienta: GitHub Actions (CI/CD)
name: Deploy to Production
on:
push:
branches: [ main ]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Deploy to Server
uses: appleboy/ssh-action@v1.0.0
with:
host: ${{ secrets.SERVER_HOST }}
username: ${{ secrets.SERVER_USER }}
key: ${{ secrets.SSH_PRIVATE_KEY }}
script: |
# Estos comandos se ejecutan en el HOST del servidor
cd /var/www/mi-app
git pull origin main
docker compose exec app composer install --no-dev --optimize-autoloader
docker compose exec app php artisan migrate --force
docker compose exec app php artisan config:cacheEn este flujo:
✅ El Git se ejecuta en el host (
git pull origin main)✅ Los comandos de construcción se ejecutan en el host (
docker compose exec)✅ El contenedor solo ejecuta el código actualizado (sin saber nada de Git)
El error común que debes evitar
# ❌ NO hagas esto en tu Dockerfile
FROM php:8.2-fpm
RUN apt-get update && apt-get install -y git # ¡NO!
RUN git clone https://github.com/mi-app.git . # ¡NO!Si haces esto, tu contenedor:
Será más grande y pesado
Tendrá credenciales expuestas (si usas autenticación)
No podrá actualizarse fácilmente (cada cambio requiere reconstruir la imagen)
No podrá usar volúmenes correctamente (el código estaría dentro del contenedor, no en el host)
Resumen final
| ¿Qué necesito? | ¿Dónde va? | ¿Por qué? |
|---|---|---|
| Git (para control de versiones) | En el HOST (tu máquina local o servidor) | Es donde se ejecutan git init, git add, git commit, git push, git pull |
| Código de la aplicación | En el HOST (sincronizado con el contenedor vía volúmenes) | Los archivos deben persistir y ser editables desde el host |
| Contenedor Docker | En el HOST (ejecuta la aplicación) | Solo debe contener lo necesario para ejecutar tu app (PHP, Nginx, MySQL) |
| Git dentro del contenedor | ❌ NO | No es necesario. El contenedor solo ejecuta el código que ya está sincronizado |
gh
Así que ya lo sabes! Git vive en el host, no en el contenedor. El contenedor es un "actor" pasivo que ejecuta el código que el host le proporciona a través de los volúmenes. El host es el "director" que orquesta todo: descarga el código con Git, lo actualiza, ejecuta migraciones y reinicia servicios.
¡Felicidades! 🎉 Ahora entiendes perfectamente la separación de responsabilidades y por qué no necesitas Git dentro del contenedor
Comentarios
Publicar un comentario