Gitlab despliegue automatico con Django

5 minutos

Gitlab runner

Los sistemas CI/CD (continuous integration y continuous delivery o continuous deployment) son cómodos para un desarrollo, cuando se realiza un commit en una rama determinada se activa un sistema automático que sincroniza el código en el servidor. Nos ahorra tiempo en comprobar errores y evitamos las monótonas acciones para mantener la web acorde al último cambio: las automatizaciones son buenas y una bendición. Por ello, en este tutorial he decidido enseñar como aplico el sistema Gitlab CI/CD para un proyecto Django. En cada commit, de una rama determinada, se lanzará un script que atravesará diferentes fases: compilación, test y despliegue. Además si existe algún problema nos avisará de inmediatamente abortando las acciones siguiente.

Requisitos

No se puede realizar esta técnica en cualquier hosting, es obligatorio disponer de:

  • Repositorio Gitlab donde almacenará el código.
  • VPS o servidor dedicado en el cual se ejecutará Django.
  • Acceso SSH al servidor.
  • Rama develop y master.

En caso contrario no será posible.

Ramas y despligues

Debemos diferenciar el desarrollo en 2 estados: no estable y para los usuarios. Cada uno dispondrá de una rama propia con un servidor separado. Con esto conseguimos un limbo seguro solo usado por el equipo para probar todo unificado, con la intención de descubrir problemas antes de que los usuarios, y otro muy estable para ser usado por los usuarios reales.

  • develop: La rama donde serán integrados los cambios del equipo. Serán desplegados en un servidor privado llamado Staging. Suele utilizarse un dominio sencillo como beta.miweb.com.
  • master: La rama principal. La que menos cambio recibe, y siempre después de limpiar cualquier fallo dentro de la rama Develop. Se le denomina Production y es el servidor que visitará los usuarios finales. Se asigna el dominio principal miweb.com.

Siguiendo esta arquitectura usaremos 2 servidores y 2 ramas.

Pasos

Dentro de Gitlab hay una pieza de software llamada Runner, es el encargado de realizar las tareas. Puede ejecutarse dentro de Gitlab o en el servidor donde se aloja el sitio. En el ejemplo seguiremos esta última estrategia.

1) Desactiva Shared Runners

En Settings → CI/CD desactiva Shared Runners para que no levante imágenes de Docker en paralelo cuando se active un Runner. De esa manera los procesos irán en cola, disponiendo de mayor rapidez y control.

También puedes reducir el numero de Git shallow clone a 0 para que no se haga ninguna sincronización con Git. Más adelante explicaremos su utilidad.

2) Configuración de repositorio.

Para configurar el Runner necesitaremos añadir un fichero con el nombre de .gitlab-ci.yml en la raiz del repositorio.

Editalo con el siguiente ejemplo.

stages:
  - prepare
  - test
  - deploy

before_staging:
  stage: prepare
  tags:
    - staging
  only:
    - develop
  script:
    - cd /home/django/django_project
    - git fetch
    - git checkout develop 
    - git reset --hard
    - git pull origin develop

before_production:
  stage: prepare
  tags:
    - production
  only:
    - master
  script:
    - cd /home/django/django_project
    - git fetch
    - git checkout master 
    - git pull origin master

linter:
  stage: test
  tags:
    - staging
  script:
    # Linter
    - cd /home/django/django_project
    - /home/django/venv/bin/black .
    # Test
    - /home/django/venv/bin/python3 manage.py test

after_staging:
  stage: deploy
  tags:
    - staging
  only:
    - develop
  script:
    - cd /home/django/django_project
    - /home/django/venv/bin/pip3 install -r requirements.txt
    # DB sync
    - /home/django/venv/bin/python3 manage.py migrate
    # Static sync
    - /home/django/venv/bin/python3 manage.py compilemessages
    - /home/django/venv/bin/python3 manage.py collectstatic --no-input
    # Restart web server
    - sudo systemctl restart gunicorn

after_production:
  stage: deploy
  tags:
    - production
  only:
    - master
  script:
    - cd /home/django/django_project
    - /home/django/venv/bin/pip3 install -r requirements.txt
    # DB sync
    - /home/django/venv/bin/python3 manage.py migrate
    # Static sync
    - /home/django/venv/bin/python3 manage.py compilemessages
    - /home/django/venv/bin/python3 manage.py collectstatic --no-input
    # Restart web server
    - sudo systemctl restart gunicorn

3) Configurar Runner

Descargamos binario de Runner y lo instalaremos en el servidor.

https://docs.gitlab.com/runner/install/

Para Ubuntu:

# Linux x86-64
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64

# Linux x86
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-386

# Linux arm
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-arm

# Linux arm64
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-arm64

# Linux s390x
sudo curl -L --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-s390

Damos permisos de escritura.

chmod +x /usr/local/bin/gitlab-runner

Creamos un usuario para Gitlab.

useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash

Instalamos servicio y lo iniciamos.

gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
gitlab-runner start

Registramos el Runner.

gitlab-runner register

Le decimos donde esta nuestro servidor de CI, que es el propio Gitlab.

Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com )
https://gitlab.com

Ahora nos pedirá el token, lo copiamos de Settings → CI/CD.

Gitlab

Le damos un nombre para identificarlo en el panel de Gitlab.

Please enter the gitlab-ci description for this runner
[hostname] my-runner

Le damos el tag que identifique el servidor, de ese modo podremos decidir que comandos ejecutará en cada uno. En el tutorial nos iniciaremos con el servidor staging.

Please enter the gitlab-ci tags for this runner (comma separated):
staging

Indicamos donde queremos ejecutar las ordenes, en este caso en el VPS/Servidor donde esta alojada la web (shell).

Please enter the executor: ssh, docker+machine, docker-ssh+machine, kubernetes, docker, parallels, virtualbox, docker-ssh, shell:
shell

4) Configuramos VPS/Servidor para que sincronice el repositorio.

Nos convertimos en el usuario del runner.

su gitlab-runner

Creamos credenciales de SSH para que el repositio pueda hacer un pull de cada cambio.

ssh-keygen -t rsa

Damos todo a enter.

Copiamos el contenido de .ssh/id_rsa.pub. Podemos ver el contenido con el siguiente comando.

less .ssh/id_rsa.pub

Lo añadimos en Gitlab, en la sección Settings → Deploy Keys.

Gitlab

Le damos un título cualquiera y pegamos en Key lo anterior (el contenido de .ssh/id_rsa.pub).

Ahora ya podemos crear un clone o realizar un pull del repositorio.

Para que gitlab-runner pueda ejecutar comandos en la carpeta de otro usuario, que será lo más habitual, tendremos que darle permisos. Le añadimos el grupo del usuario que vayamos a modificar sus archivos. Por ejemplo, si tengo un usuario que se llama django y dentro de su carpeta home debe estar mi proyecto de Django.

sudo usermod -a -G django gitlab-runner

Ahora buscamos la carpeta donde queramos clonar el proyecto, o trabajar, y le damos permisos de lectura, escritura y ejecución para los grupos.

sudo chmod g+rwx tu_proyecto

Para poder usar el comando sudo necesitaremos.

visudo

Y añadir

gitlab-runner ALL=(ALL) NOPASSWD: ALL

Ya podemos clonar

git clone url-proyecto .

5) Comprueba.

Ya ha llegado el momento de subir un cambio a Develop y ver como se ejecuta en CI/CD -> Pipeline. Si todo se ha ejecutado correctamente lo marcará como Passed, sino te proporcionará un informe.

El último paso consiste en repetir los pasos del 3 en adelante para Production cambiando:

Please enter the gitlab-ci tags for this runner (comma separated):
production

Espero que os sea de utilidad.

Comentarios

{{ comments.length }} comentarios

Nuevo comentario

Nueva replica  {{ formatEllipsisAuthor(replyComment.author) }}

Acepto la política de Protección de Datos.

Escribe el primer comentario

Tal vez también te interese...