Realizar un deploy automático desde un repositorio GIT a un servidor remoto

Durante años mi forma de poner un sistema web en producción consistía en abrir filezilla y copiar los archivos sobre la carpeta www, pero esa forma de trabajar crea muchos inconvenientes. Puede que solo pierdas tiempo, pero posiblemente en alguna ocasión te paso que se te olvidó subir un archivo que no recordabas que habías modificado, o sobreescribiste un archivo y no supiste cual fue, o alguien mas sobreescribio un cambio que tu realizaste, etc. Si usas repositorios para trabajar en tu código seguro que no tendrás mayores problemas, y si ya usamos repositorios para el desarrollo ¿por que no usar repositorios para realizar el deploy de nuestra aplicación y evitarnos estos inconvenientes?

El proceso descrito abajo esta basado en un servidor ubuntu hosteado en DigitalOcean, pero estos conceptos se aplican a cualquier servidor linux realizando los respectivos ajustes.

 

Preparar el servidor

Lo primero que debemos hacer es instalar GIT en nuestro servidor, en mi caso ejecuto el siguiente comando:

sudo apt-get install git

Una vez instalado git creamos un usuario que será con el que nos conectaremos para realizar el push, en mi caso lo llame “git”. Para que este usuario pueda funcionar como conexión con nuestro repositorio se debe configurar que los comandos que reciba se ejecuten a traves de git, para eso usamos la opción -s /usr/bin/git. El comando debería lucir así:

sudo useradd -m -s /usr/bin/git-shell git

Si tenemos alguna clave pública de conexión la podemos agregar a nuestro usuario git para que pueda autenticarse en el momento de la conexión. Lo que vamos a hacer es cambiar de usuario a git, ingresar a la carpeta home de git, crear una carpeta .ssh y copiar la clave pública en un archivo llamado authorized_keys:

sudo -u git bash
cd ~
## cd /home/git
mkdir -p .ssh
vim .ssh/authorized_keys

este comando debe abrir el editor de texto vim en nuestra consola, ahí debemos copiar nuestra clave pública y grabar. Si tienes una conexión FTP y acceso al directorio /home/git, entonces tambien lo puedes hacer copiando el archivo desde tu maquina al servidor. Si lo haces de la segunda forma, asegurate que el usuario git sea el propietario del archivo y tenga los permisos adecuados. Recuerda que la clave pública debe empezar por ssh-rsa seguido de un espacio y la cadena de datos cifrados, todo en una sola linea.

 

Configurar el repositorio remoto

Con git instalado y nuestro usuario de conexión listo, vamos a crear nuestro repositorio remoto. nos ubicamos en la carpeta donde estará el repositorio, puede ser dentro de la carpeta home del usuario git o en cualquier otra parte del sistema. Cuando estemos situados en la ruta que hayamos definido, crearemos la carpeta que contendrá nuestro repositorio e ingresamos a ella. En mi caso voy a ubicar el repositorio en /home/git/proyecto-remoto, los comandos que he usado son:

cd ~
## cd /home/git
mkdir proyecto-remoto
cd proyecto-remoto

Ahora iniciamos un repositorio minimo mediante el siguiente comando:

git init --bare

Git trabaja mediante archivos comprimidos que contienen todos los cambios que se realizaron en el commit. Es por esto que cuando realicemos el push al servidor, no veremos nuestros archivos en la carpeta proyecto-remoto. Para obtener los archivos de la misma forma que en nuestra maquina local, haremos uso de los hooks que tiene git. En especifico, haremos uso del hook post-receive que se ejecuta automáticamente despues de que se ha realizado un push al servidor. Para esto creamos el archivo post-receive dentro de la carpeta hooks de nuestro repositorio:

cd ~/proyecto-remoto/hooks
## cd /home/git/proyecto-remoto/hooks
vim post-receive

Se nos abrirá el editor de texto y dentro copiamos lo siguiente:

#!/bin/bash
git --work-tree=/var/www/html/deploy-folder --git-dir=/home/git/proyecto-remoto checkout -f

Este script se ejecuta automáticamente despues de que el push se haya completado y lo que hace es expandir los archivos que recibe el repositorio. La carpeta deploy-folder será el lugar donde se copiaran nuestros archivos descomprimidos para que entren a producción. Guardamos los cambios, y dado que es un script, lo hacemos ejecutable para el usuario git:

chown git /home/git/proyecto-remoto/hooks/post-receive
chmod +x /home/git/proyecto-remoto/hooks/post-receive

Tambien debemos dar los permisos necesarios para poder copiar los archivos a la carpeta deploy-folder:

chown git /var/www/html/deploy-folder
chmod 775 /var/www/html/deploy-folder

Lo que hemos hecho hasta ahora ha sido configurar nuestro servidor para podernos conectarnos mediante git, crear nuestro repositorio y decirle que cada vez que hagamos un push, expanda los archivos a la carpeta de produccion. Ahora configuraremos nuestro repositorio local para poder enviar los cambios al servidor.

Configurar el repositorio local

En esta parte vamos a asummir que ya tenemos configurado git en nuestra maquina local, hemos clonado un repositorio y estamos listo para enviar a producción. Lo primero que debemos hacer es agregar nuestro servidor en el listado de repositorios remotos, para esto usamos los siguientes comandos:

git remote add production git@miproyecto.com:/home/git/proyecto-remoto

Algunos detalles de este comando son:

  • production es el nombre con el que identificaremos a nuestro servidor dentro del git local
  • git@miproyecto.com corresponde al usuario que creamos al inicio “git” y miproyecto.com es el dominio de nuestro servidor, tambien puede reemplazarse esto por la ip pública del servidor si es que no tiene dominio.
  • /home/git/proyecto-remoto es la carpeta dentro de nuestro servidor donde está alojado nuestro repositorio

Cuando se haya añadido el repositorio remoto, probaremos que todo funcione. Primero crearemos un archivo index.html con el texto “Deploy desde GIT”:

echo "<h2>Deploy desde GIT</h2>" >> index.html

Tambien lo podemos hacer desde un editor de texto y guardar el archivo en la carpeta de nuestro repositorio. Ahora realizaremos el push sobre nuestro servidor

git add .
git commit -m "Probando el deploy con git"
git push production master

Si todo estuvo correcto, podremos ver los cambios reflejados en nuestro servidor. Entramos desde nuestro navegador a https://miproyecto.com/deploy-folder y debería aparecernos el mensaje “Deploy desde GIT”.

Errores que encontre

El primer error que encontre fue al configurar la dirección del repositorio remoto en mi maquina local, inicialmente le ponia el prefijo http:// pero si se hace eso git lo asume como un repositorio de solo lectura y no envia la información. En tal caso quitandole el prefijo del protocolo funciona.

El segundo error que me daba era que al hacer push el script post-receive no se ejecutaba. Eso era por que no tenia permisos de ejecución y tampoco era propiedad del usuario git, por lo que no podía realizar la acción.

El tercer problema que me dió fue por los permisos de la carpeta deploy-folder, el usuario git no tenía permisos de escritura sobre ella y por consiguiente no podía copiar los archivos ahí. Haciendo chown git y chmod 775 se soluciona, sin embargo, puede que al cambiar de usuario la carpeta no pueda ser vista por el webserver. En el caso de docker no hay ese problema, pero si se usa apache o nginx es posible que sea necesario agregar el usuario www-data como copropietario de la carpeta.

Conclusiones

Mediante este proceso tendremos un método de deploy mucho más seguro y fácil de manejar. Al tener todas las ventajas de un repositorio podemos permitir que varias personas realicen actualizaciones, hacer rollbacks en caso de error y reducir tiempo y errores al copiar archivos. Una forma de mejorar la configuración actual sería reducir el push a una sola rama, por ejemplo, solo permitir hacer push de la rama master. También podriamos hacer push de una rama de desarrollo y enviarla a un subdominio para poder hacer pruebas de la aplicación sin necesidad de enviarlas al servidor de producción. Incluso podríamos configurar que el post receive nos envíe alertas, para saber cada vez que alguien hace un deploy.

Espero que este tutorial les ayude a implementar este proceso de deploy en sus servidores y de esta forma mejorar sus procesos de puesta en producción. Exitos a todos y nos vemos en la próxima!

 

Fuentes:

 

 

 

 

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s