Originalmente, esta era una publicación completa, pero se hizo tan grande que tuve que dividirla en 2. Esto continúa desde la publicación n.º 2, Configure GitLab CI en AWS EC2 usando Docker. Publicaciones: [Tutorial — Guía] Instalación de GitLab, GitLab CI en AWS EC2 desde cero. Configurar GitLab CI en AWS EC2 mediante Docker (Esta publicación) Configuración de .gitlab-ci.yml Solución de problemas de GitLab y GitLab CI #1- Entendiendo el archivo .gitlab-ci.yml El archivo es un archivo que en Este archivo se ejecuta automáticamente una confirmación al servidor. Esto desencadena una notificación al corredor que especificó en el n. ° 3 y luego procesa la serie de tareas que especificó. Entonces, si lo presiona 3 veces, ¡lo ejecutará 3 veces! Es por eso que si está impulsando múltiples, desea un corredor más rápido o un corredor separado por máquina. .gitlab-ci.yml YAML crea la raíz de su proyecto. cada vez que envía Tenga en cuenta que, dado que usamos , las tareas siempre comienzan en un estado limpio de la imagen. Esto significa que todos los archivos y modificaciones que coloque o haga dentro de .gitlab-ci.yml se revertirán cada vez que envíe una confirmación al servidor. Puede evitar esto especificando cachés. Docker El contenido de los archivos está compuesto por las claves que podrá encontrar en esta No hay ningún orden que deba seguir, pero tenga . Esto puede compensar o deshacer su proyecto. Puede verificar con un para ver si funciona antes de presionar. página. mucho cuidado con las sangrías filtro YAML en línea Estaré trabajando en una aplicación de ejemplo. Con Karma como corredor de pruebas. He publicado un .gitlab-ci.yml que usé en uno de mis proyectos anteriores en (¡Por favor, míralo!) NodeJS este GitHub Gist . puede darle otra perspectiva. Esta página Desglosándolo: imagen: nodo: 9.4.0 La clave de imagen toma una imagen de y la usa como imagen base. GitLab basará todas las pruebas en esta imagen. Si está realizando un proyecto en Ruby, Java, Go, PHP, etc., especifique la imagen correcta de Docker Hub. Docker Hub cache:paths:- node_modules/- .yarn Esto crea una carpeta de caché temporal que evita que y se vuelvan a crear cada ejecución de CI (cada vez que realiza una confirmación). node_modules .yarn antes_script: apt-get update -qq && apt-get install otro comando que se ejecutará después del anterior puedes seguir agregando líneas y líneas. le dice a GitLab que ejecute lo que haya especificado antes que nada. Puede considerar esto como un guión de preparación. before_script #1.1 Etapas de comprensión Las etapas son una serie de pasos por los que pasa su código para llegar a su destino final (Producción). GitLab le permite definir cualquier número de etapas con cualquier nombre. Lo hace especificándolo bajo la clave de etapa, en en que desea que se ejecuten. el orden Luego, GitLab irá ejecutando cada uno de ellos, paso a paso. Si uno de ellos falla, impide la ejecución de los siguientes. etapas: construir prueba puesta en escena abiertoSr. producción En la parte anterior, ejecutará primero la etapa de , hasta llegar a la . build production #1.2 Definición de las acciones de las etapas en el archivo .gitlab-ci.yml Usted define qué etapa se ejecutará especificando primero una clave principal de nombre de etapa. Esta clave . puede tener el nombre que desee y puede contener espacios Por ejemplo: Build My App:stage: buildtags:#- you_would_put_your_tag_in_here#- nodebefore_script: conjunto de configuración de hilo carpeta de caché .yarn hilo installscript: - compilación de ejecución de npm El nombre de la etapa es y especifica una clave llamada que hace referencia a la etapa que creó anteriormente, en la lista de etapas. Build My App stage before_script se ejecuta igual que el que especificamos anteriormente, solo en el contexto de la etapa de : nada se ejecutará hasta que se ejecuten esos scripts. build En este caso, estamos usando en lugar de , y está creando una carpeta de caché que contendrá toda la configuración de yarn, que no se volverá a crear en la ejecución de cada proyecto (cada vez que ingrese al repositorio) yarn npm #1.3 Etiquetas Si siguió el artículo anterior que escribí sobre "etiquetas" ( ), ¡aquí es donde las especificamos! Si las etiquetas coinciden con la que especificamos en el corredor, esto activará el corredor una vez que haya terminado. Usted especifica cada etiqueta en su propia línea. Si se refiere al ejemplo anterior, si elimina el antes del , eso significa que esa etapa específica solo funcionará en los corredores con la etiqueta de nodo. Si no especifica ninguna etiqueta (omita la clave de ), puede conectarse al corredor (siempre que no esté bloqueado en el proyecto actual). Punto #3.1, del artículo 2 # node tags Nota: 5.4–5.6 Es una descripción general de las partes del archivo. Estoy explicando con más detalle POR QUÉ, cómo y Cuáles son los contenidos en el #7. #1.4 Entorno de prueba Una vez más, no importa cómo nombre su escenario. En este caso, simplemente lo llamé "Prueba" para probar. Test:stage: testbefore_script:- yarn config set cache-folder .yarn- yarn installscript: Instala cromo - wget -q -O — [https://dl-ssl.google.com/linux/linux\_signing\_key.pub](https://dl-ssl.google.com/linux/linux_signing_key.pub) | apt-key add - - echo 'deb \[arch=amd64\] [http://dl.google.com/linux/chrome/deb/](http://dl.google.com/linux/chrome/deb/) stable main' | tee /etc/apt/sources.list.d/google-chrome.list - apt-get update - apt-get install google-chrome-stable -y # Runs the tests. - npm run test:karma-headless Hay mucho que hacer allí. La metodología de integración continua se basa en las pruebas que ejecuta en su máquina local. Esas pruebas van acompañadas de su ejecución en la máquina real que va a implementar. Dado que esto es muy específico para Node y JavaScript (de lo que está hecho mi proyecto), necesito preparar el campo para que puedan ejecutarse perfectamente. En este caso, utilizo karma como corredor de pruebas para ejecutar todas mis pruebas locales. Requiere de un navegador web local, en este caso, Google Chrome. Por lo tanto, necesito emitir un comando de instalación de Google Chrome (recuerde que cada vez que presionamos, todo comienza desde un estado limpio) y ejecutar las pruebas. Si todas las pruebas tienen éxito, GitLab pasará automáticamente a la siguiente sección. #1.5 Abrir una solicitud de fusión # Recuerde tener el PRIVATE_TOKEN generado. Esto solo debe hacerse una vez por proyecto y no por usuario. # Una vez que lo agregue (necesita privilegios de maestro) como variable secreta, debería funcionar. Solicitud de combinación abierta: # Lo obtuve de aquí: imagen: tmaier/gitlab-auto-merge-requeststage: openMrscript:- bash ./gitlab-deploy/auto-merge-request.sh # El nombre del script https://gitlab.com/tmaier/gitlab-auto-merge-request/blob/develop/.gitlab-ci.yml Después de que nuestro entorno de prueba tenga éxito, queremos que GitLab abra automáticamente una solicitud de fusión que podamos fusionar con éxito para dominar si pasa. # 1.6 Entornos de puesta en escena y producción Implementar en Staging:stage: stagingbefore_script: Genera para conectarse a la unidad de AWS la clave SSH. mkdir -p ~/.ssh echo -e “$SSH_PRIVATE_KEY” > ~/.ssh/id_rsa Establece el permiso en 600 para evitar un problema con AWS que está demasiado desprotegido. chmod 600 ~/.ssh/id_rsa '[[ -f /.dockerenv ]] && echo -e “Host *\n\tStrictHostKeyChecking no\n\n” > ~/.ssh/config' secuencia de comandos: - bash ./gitlab-deploy/.gitlab-deploy.staging.shenvironment:name: staging Expone un botón que, cuando se hace clic, lo lleva a la URL definida: url: [http://ec2-11-44-514-91.us-east-2.compute.amazonaws.com:3001](http://ec2-13-59-173-91.us-east-2.compute.amazonaws.com:3001) Implementar en Production:stage: productionbefore_script: Genera para conectarse a la unidad de AWS la clave SSH. - mkdir -p ~/.ssh - echo -e "$SSH\_PRIVATE\_KEY" > ~/.ssh/id\_rsa Establece el permiso en 600 para evitar un problema con AWS que está demasiado desprotegido - chmod 600 ~/.ssh/id\_rsa - '\[\[ -f /.dockerenv \]\] && echo -e "Host \*\\n\\tStrictHostKeyChecking no\\n\\n" > ~/.ssh/config' script:- bash ./gitlab-deploy/.gitlab-deploy.prod.shenvironment:name: production# Expone un botón que, cuando se hace clic, lo lleva a la URL definida: url: http://ec2-13-59-173- 91.us-east-2.compute.amazonaws.com:81 cuando: manuales Hablaré sobre el contenido de esto en la parte inferior. #2 Tuberías Cuando envías el repositorio de git a GitLab con el archivo , activará automáticamente las canalizaciones. Las canalizaciones son las etapas que definiste en tu En nuestro caso, tenemos build, test, staging, openMr y production. Cada una de esas marcas que ves en la captura de pantalla anterior representa cada una de las etapas. Una cruz roja representará una etapa fallida. Una marca de verificación verde indicará que la prueba pasó con éxito. La barra diagonal identificará que la prueba fue cancelada. .gitlab-ci.yml .gitlab-ci.yml. Puede ver una interfaz de línea de comandos que le muestra el desarrollo de cada una de las etapas haciendo clic en el icono y luego haciendo clic en la ventana emergente: Esta es la pantalla que le muestra después de que la etapa de construcción se haya completado con éxito. #3- Integración a AWS. Cómo conectar la instancia de GitLab a la instancia de EC2 con su proyecto Uno de los mayores desafíos es integrar la canalización de CI con su proyecto. , GitLab no ofrece una forma nativa de hacer esto. Puede enviar su código a y luego realizar la migración desde allí. Hasta donde sé yo AWS Code Deploy Hay una fantástica que lo guiará a través de ese proceso por autronix de stackoverflow: guía paso a paso _He creado un conjunto de archivos de muestra para acompañar la guía proporcionada a continuación._stackoverflow.com Cómo implementar con Gitlab-Ci en EC2 mediante AWS CodeDeploy/CodePipeline/S3 . Haga lo siguiente si por casualidad no funciona. Recomiendo el enfoque anterior sobre el que les voy a mostrar el enfoque de autronix Esta integración transmite el uso de git (extraemos el repositorio fusionado de GitLab) y lo actualizamos en nuestra instancia EC2, ejecutamos el script de recarga desde npm (suponemos que estamos usando Node en este proyecto) y publicamos los cambios. Puede ver, a estas alturas, que esto parece más un truco que una solución real. Es en entornos muy distribuidos en los que necesite replicar el código base en varias instancias de EC2. Pero, de nuevo, se trata de tener opciones, ¿verdad? posible que esto no funcione #4: prepare la máquina EC2 que aloja el código implementado. Este enfoque está inspirado en . este post Tratamos la máquina EC2, la que aloja el código en producción, como un cliente de GitLab. Creamos una clave SSH que se conecta a GitLab y extraemos el código de allí. Si recuerdas, del primer tutorial: ssh-keygen -t rsa -C “tu_nombre@tu_correo.com” ssh-add ~/.ssh/id_rsa Si tuvo problemas para agregar la clave, intente ejecutar esto primero ( ): Fuente eval `ssh-agent -s`ssh-add ~/.ssh/id_rsa Una cosa acerca de este enfoque es que no he encontrado una manera de hacer que funcione con una frase de contraseña, así que cuando te pregunte al respecto, ¡ ! déjalo en blanco Cuando crea la clave, se encuentra en: ~/.ssh/id_rsa.pub Tenga en cuenta que esta vez no podrá copiar su contenido en el portapapeles a menos que instale "clip" Nota: Esto consumirá más de 300 MB de espacio en disco. No lo haga a menos que no esté limitado por el espacio en disco. sudo apt-obtener clip de instalación gato ~/.ssh/id_rsa.pub | acortar Otra opción es simplemente ejecutar cat y copiar el resultado del comando. gato ~/.ssh/id_rsa.pub Para controlar los posibles riesgos de seguridad, le recomiendo que cree un usuario independiente en GitLab que maneje solo una extracción del repositorio y nada más. Adjuntas la clave pública a esa cuenta. Creé un usuario fantasma en GitLab que maneja la extracción de GitLab. Vaya a /admin en su dirección de GitLab. (También puede hacer clic en el icono de la herramienta en la barra de navegación) Crear un nuevo usuario: Desmarque "puede crear un grupo". Nivel de acceso “Regular”, Externo “marcado”. Vaya al proyecto con el que tiene su repositorio: Busque el nuevo miembro que creó y configúrelo como Reportero. Vaya a la pestaña Usuarios en el área de administración y haga clic en el nombre del usuario creado recientemente: Haga clic en "Suplantar" y vaya a la página de claves ssh. #5- El entorno de Staging, configuración: Aquí es donde empiezo a explicar qué diablos fue lo que puse arriba. Deploy to Staging:stage: stagingbefore_script:# Genera para conectarse a la unidad de AWS la clave SSH.- mkdir -p ~/.ssh- echo -e “$SSH_PRIVATE_KEY” > ~/.ssh/id_rsa# Establece el permiso en 600 para evitar un problema con AWS# que está demasiado desprotegido.- chmod 600 ~/.ssh/id_rsa- '[[ -f /.dockerenv ]] && echo -e “Host *\n\tStrictHostKeyChecking no\n\n” > ~ /.ssh/config' secuencia de comandos: - bash ./gitlab-deploy/.gitlab-deploy.staging.sh environment:name: staging# Expone un botón que, cuando se hace clic, lo lleva a la URL definida:url: http://ec2-13-14-444-91.us-east-2.compute.amazonaws.com:3001 #5.1- Comunicación con la instancia EC2. Necesitamos una forma de comunicarnos con la unidad de AWS. La forma en que hacemos esto es tomando la clave (¡Cuidado! Información confidencial) del id_rsa generado (El que generamos dentro de nuestra instancia EC2) y enviándolo con nuestro script de shell predefinido (De lo cual hablaré más en un momento ). privada El código en before_script lo que hace es que genera un archivo en blanco llamado id_rsa (que coincide con la convención para la clave privada). Lo completamos con una variable personalizada (más sobre eso ahora) cada vez que se ejecuta el proyecto. GitLab CI le permite almacenar variables en la configuración del proyecto: Vaya a Su proyecto -> Configuración -> CI/CD -> Variables secretas Lo que vamos a hacer es tomar el contenido de la id_rsa (clave privada, la que no tiene .pub) y vamos a copiar y pegar su contenido. Hacemos el mismo procedimiento que hicimos con el archivo público (Tenga en cuenta que este es el id_rsa sin extensión): gato ~/.ssh/id_rsa | acortar O, si no instaló el clip, cópielo y péguelo desde la consola: gato ~/.ssh/id_rsa Vamos a copiar y pegar ese valor en el formulario de "Variables secretas" y darle una "SSH_PRIVATE_KEY" (Esto coincide con el de y puedes verlo en la imagen de arriba) .gitlab-ci.yml Una vez que lo tengas, haz clic en “Guardar variables”. #5.2- Crear un Shell Script para el entorno de Staging Todavía necesitamos indicar a GitLab que ejecute la solicitud de extracción en nuestro entorno EC2. Para la separación de preocupaciones y la capacidad de mantenimiento, podemos especificar un archivo de shell externo que ejecutará la extracción desde la rama principal. Llamamos a este archivo Puede llamar a este archivo como desee. Solo recuerda especificarlo en el archivo . .gitlab-deploy.staging.sh .gitlab-ci.yml Así tengo estructurado mi proyecto. está en la raíz. Mientras que los archivos de shell están en una carpeta llamada . Por lo tanto, hacemos referencia a ellos como . .gitlab-ci.yml gitlab-deploy ./gitlab-deploy/.gitlab-deploy.staging.sh El contenido del archivo es el siguiente: #!/bin/bash # Obtener lista de servidores: establecer — f # Variables del servidor GitLab:# Nota: ¡¡No pueden tener espacios!!string=$DEPLOY_SERVERarray=(${string//,/ })# Iterar servidores para implementar y extraer la última confirmación# Cuidado con ; para i en “${!array[@]}”; doecho “Implementar proyecto en el servidor ${array[i]}”ssh ubuntu@${array[i]} “cd ./Staging/vr && git stash && git checkout $CI_BUILD_REF_NAME && git stash && git pull && sudo yarn install && sudo npm ejecutar puesta en escena” https://stackoverflow.com/a/20666248/1057052 hecho Como puede ver, lo que estamos haciendo aquí es que estamos ejecutando un git pull y una instalación de los paquetes en el servidor de ensayo. Era barato y estaba ejecutando ambos: producción y pruebas en el mismo servidor (expuse diferentes puertos). Te recomiendo que tengas diferentes máquinas para eso. La variable es otra variable personalizada que creamos en la página de variables secretas con la dirección IPv4 de nuestra instancia EC2: $DEPLOY_SERVER Vaya a Su proyecto -> Configuración -> CI/CD -> Variables secretas La clave de entorno que especifica el nombre y la URL es "solo para mostrar". Esto le mostrará un botón en la etapa de la consola que le indicará la URL que especifique allí. Esto es opcional y se puede omitir. #6 Abrir solicitudes de combinación automáticamente GitLab no abrirá automáticamente las solicitudes de combinación. Es por eso que tenemos que hacer un poco de trabajo nosotros mismos para que funcione. Esto se hace a través de una imagen Docker de tmaier de GitHub # Recuerde tener el PRIVATE_TOKEN generado. Esto solo debe hacerse una vez por proyecto y no por usuario. # Una vez que lo agregue (necesita privilegios de maestro) como variable secreta, debería funcionar. Solicitud de combinación abierta: # Lo obtuve de aquí: imagen: tmaier/gitlab-auto-merge-requeststage: openMrscript:- bash ./gitlab-deploy/auto-merge-request.sh # El nombre del script https://gitlab.com/tmaier/gitlab-auto-merge-request/blob/develop/.gitlab-ci.yml Este es el archivo auto-merge-request.sh #!/usr/bin/env bashset -e # Obtenido de: # # Esto creará automáticamente una solicitud de fusión justo después de que se haya enviado la compilación. # Se agregaron algunos toques de: https://about.gitlab.com/2017/09/05/how-to-automatically-create-a-new-mr-on-gitlab-with-gitlab-ci/ https://gitlab.com/tmaier/gitlab-auto-merge-request/blob/develop/merge-request.sh si [-z “$PRIVATE_TOKEN”]; thenecho “PRIVATE_TOKEN no establecido”echo “Configure el token privado de GitLab como PRIVATE_TOKEN”exit 1fi # Extraiga el host donde se ejecuta el servidor y agregue la URL a las API [[ $CI_PROJECT_URL =~ ^https?://[^/]+ ]] && HOST=”${BASH_REMATCH[0]}/api/ v4/proyectos/” # Mira cuál es la rama predeterminada TARGET_BRANCH=`curl — silencioso “${HOST}${CI_PROJECT_ID}” — encabezado “PRIVATE-TOKEN:${PRIVATE_TOKEN}” | jq — salida sin procesar '.default_branch'`; # La descripción de nuestro nuevo MR, queremos eliminar la rama después de que el MR se haya # cerradoBODY=”{\”id\”: ${CI_PROJECT_ID},\”source_branch\”: \”${CI_COMMIT_REF_NAME}\”, \”target_branch\”: \”${TARGET_BRANCH}\”,\”remove_source_branch\”: true,\”title\”: \”WIP: ${CI_COMMIT_REF_NAME}\”,\”assignee_id\”:\”${ ID_USUARIO_GITLAB}\”}”; # Requerir una lista de todas las solicitudes de combinación y mirar si ya hay # una con la misma fuente branchLISTMR=`curl — silencioso “${HOST}${CI_PROJECT_ID}/merge_requests?state=opened” — encabezado “PRIVATE- TOKEN:${PRIVATE_TOKEN}”`;COUNTBRANCHES=`echo ${LISTMR} | grep -o “\”source_branch\”:\”${CI_COMMIT_REF_NAME}\”” | wc -l`; # No se encontró MR, vamos a crear uno nuevoif [ ${COUNTBRANCHES} -eq “0” ]; thencurl -X POST “${HOST}${CI_PROJECT_ID}/merge_requests” \— encabezado “PRIVATE-TOKEN:${PRIVATE_TOKEN}” \— encabezado “Content-Type: application/json” \— datos “${BODY}” ; echo “Abrió una nueva solicitud de combinación: WIP: ${CI_COMMIT_REF_NAME} y se le asignó”;salir;fi echo “No se abrió ninguna nueva solicitud de fusión”; Para que esto funcione, necesitamos generar un que es solo un token aleatorio que podemos generar. Para tener un token fuerte y seguro, podemos usar un o cualquier otra cosa (¡usted elige!). PRIVATE_TOKEN generador de contraseñas Coloque los contenidos dentro de las "Variables secretas" como PRIVATE_TOKEN Vaya a Su proyecto -> Configuración -> CI/CD -> Variables secretas #7 Implementar en Producción Es muy similar al proceso de puesta en escena, pero aquí radica una diferencia. La principal diferencia entre un enfoque de CI (Integración continua) y de Implementación continua (CD) es que este último, cualquier cambio que realice en el código, se envía automáticamente a producción. En GitLab podemos especificar si lo desplegamos manualmente en producción o no especificando una clave de "cuándo". Implementar en Production:stage: productionbefore_script: Genera para conectarse a la unidad de AWS la clave SSH. - mkdir -p ~/.ssh - echo -e "$SSH\_PRIVATE\_KEY" > ~/.ssh/id\_rsa Establece el permiso en 600 para evitar un problema con AWS que está demasiado desprotegido - chmod 600 ~/.ssh/id\_rsa - '\[\[ -f /.dockerenv \]\] && echo -e "Host \*\\n\\tStrictHostKeyChecking no\\n\\n" > ~/.ssh/config' script:- bash ./gitlab-deploy/.gitlab-deploy.prod.shenvironment:name: production# Expone un botón que, cuando se hace clic, lo lleva a la URL definida: url: http://ec2-13-59-173- 91.us-east-2.compute.amazonaws.com:81 cuando: manuales Como puede ver al especificar la clave , le decimos a GitLab envíe el código automáticamente a producción y que espere nuestros comandos. when:manual que no En la página de canalizaciones, hace clic en un botón Reproducir para "Implementar en producción", que es el nombre que especificó en .gitlab-ci.yml Por último, pero no menos importante, verifique .gitlab-deploy.prod.sh #!/bin/bash # Obtener lista de servidores: establecer — f # Variables del servidor GitLab:# Nota: ¡¡No pueden tener espacios!!string=$DEPLOY_SERVERarray=(${string//,/ }) # Iterar servidores para implementar y extraer la última confirmación # Cuidado con ; para i en “${!array[@]}”; doecho “Implementar proyecto en el servidor ${array[i]}”ssh ubuntu@${array[i]} “cd ./Pardo/vr && git stash && git checkout $CI_BUILD_REF_NAME && git stash && git pull origin master && sudo yarn instalar && sudo npm ejecutar producción” https://stackoverflow.com/a/20666248/1057052 hecho Si te fijas, verás que es similar (por no decir idéntico) al de la puesta en escena. Con la excepción de que lo apunto a una ubicación diferente dentro de mi instancia EC2, donde se encuentra el código de producción. Usted es libre de modificar este archivo también. #8 ¡La canalización de CI/CD ha sido configurada! ¡Hora de empujar! ¡¡Sí!! ¡Por fin es ese momento! ¡Confirme su archivo y envíelo a su instancia de GitLab! ¡Vea cómo sus cambios comienzan a suceder! ¡Eso es todo! ¡GUAU! Gracias por el aventón.