Proceso de desarrollo y prueba con Docker y Gitlab CI

Les invito a conocer el informe de Alexander Sigachev de Inventos titulado «El proceso de desarrollo y pruebas con Docker + Gitlab CI»

Aquellos que recién comienzan a implementar el proceso de desarrollo y pruebas con Docker + Gitlab CI a menudo se hacen preguntas básicas. ¿Por dónde empezar? ¿Cómo organizarlo? ¿Cómo probar?

Esta presentación es valiosa porque describe de manera estructurada el proceso de desarrollo y pruebas utilizando Docker y Gitlab CI. El informe es de 2017. Creo que de este informe se pueden extraer fundamentos, metodologías, ideas y experiencias de uso.

Reproducir video

A quienes les interese, les invito a leer más.

Me llamo Alexander Sigachev. Trabajo en la empresa Inventos. Compartiré mi experiencia utilizando Docker y cómo lo estamos implementando gradualmente en los proyectos de la empresa.

Tema de la presentación: El proceso de desarrollo utilizando Docker y Gitlab CI.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Esta es mi segunda presentación sobre Docker. En el momento de mi primera presentación, utilizábamos Docker solo en desarrollo en las máquinas de los desarrolladores. Había alrededor de 2-3 personas que usaban Docker. Con el tiempo, adquirimos experiencia y avanzamos un poco más. Enlace a nuestra primera presentación.

¿Qué habrá en esta presentación? Compartiremos nuestra experiencia sobre los desafíos que encontramos y cómo resolvimos varios problemas. No siempre fue fácil, pero nos permitió avanzar.

Nuestro lema: dockeriza todo lo que nuestras manos alcanzan.

Proceso de desarrollo y prueba con Docker y Gitlab CI

¿Qué problemas resolvemos?

Cuando hay varios equipos en la empresa, un programador se convierte en un recurso compartido. A veces, hay etapas en las que se saca a un programador de un proyecto y se le asigna a otro proyecto por un tiempo.

Para que el programador se adapte rápidamente, necesita descargar el código fuente del proyecto y poner en marcha el entorno lo más pronto posible, lo que le permitirá seguir adelante resolviendo las tareas de este proyecto.

Normalmente, si se empieza desde cero, hay poca documentación en el proyecto. La información sobre cómo configurarlo solo está en manos de los veteranos. Los empleados configuran su espacio de trabajo por su cuenta en uno o dos días. Para acelerar esto, utilizamos Docker.

La siguiente razón es la estandarización de las configuraciones en desarrollo. Según mi experiencia, los desarrolladores siempre muestran iniciativa. En uno de cada cinco casos, se introduce un dominio personalizado, por ejemplo, vasya.dev. Al lado está el vecino Petya, que tiene el dominio petya.dev. Desarrollan un sitio o algún componente del sistema utilizando este nombre de dominio.

Cuando el sistema se expande y estos nombres de dominio comienzan a aparecer en las configuraciones, surge un conflicto de entornos de desarrollo y se sobrescribe la ruta del sitio.

Lo mismo ocurre con la configuración de la base de datos. Algunos no se preocupan por la seguridad y trabajan con la contraseña vacía de root. A otros, durante la instalación, MySQL les pidió una contraseña y esta resultó ser 123. A menudo sucede que la configuración de la base de datos se modifica constantemente dependiendo del commit del desarrollador. Alguien la corrigió, alguien no. Hubo trucos en los que sacábamos alguna configuración de prueba en .gitignore y cada desarrollador debía instalar la base de datos. Esto complicaba el proceso de inicio. Además de todo, hay que recordar la base de datos. Hay que inicializar la base de datos, establecer la contraseña, definir el usuario, crear la tabla, y así sucesivamente.

Otro de los problemas son las diferentes versiones de las bibliotecas. A menudo, el desarrollador trabaja con diferentes proyectos. Hay un proyecto legado que se inició hace cinco años (desde 2017, nota de la redacción). Al principio se empezó con MySQL 5.5. Y hay proyectos más modernos, donde tratamos de implementar versiones más actuales de MySQL, como 5.7 o superiores (en 2017, nota de la redacción).

Quien trabaja con MySQL sabe que estas bibliotecas arrastran dependencias. Es bastante problemático ejecutar 2 bases de datos al mismo tiempo. Por lo menos, es complicado conectar a antiguos clientes a la nueva base de datos. Esto, a su vez, genera varios problemas.

El siguiente problema es que, cuando un desarrollador trabaja en su máquina local, utiliza recursos locales, archivos locales, RAM local. Toda la interacción durante el desarrollo de soluciones se lleva a cabo bajo el supuesto de que funciona en una sola máquina. Un ejemplo puede ser cuando en Producción tenemos 3 servidores backend, y el desarrollador guarda archivos en el directorio raíz y desde allí nginx toma los archivos para responder a las solicitudes. Cuando ese código llega a Producción, resulta que el archivo está presente en uno de los 3 servidores.

Actualmente se está desarrollando el ámbito de los microservicios. Al dividir nuestras grandes aplicaciones en pequeños componentes que interactúan entre sí, se permite seleccionar tecnologías adecuadas para un conjunto específico de tareas. Además, esto permite dividir el trabajo y la responsabilidad entre los desarrolladores.

El desarrollador Frontend, al trabajar con JS, prácticamente no influye en el Backend. El desarrollador Backend, a su vez, desarrolla, en nuestro caso, Ruby on Rails, y no interfiere con el Frontend. La interacción se realiza a través de API.

Como bonificación, gracias a Docker hemos logrado optimizar los recursos en Staging. Cada proyecto, debido a su especificidad, requería configuraciones particulares. Era necesario destinar un servidor virtual por proyecto y configurarlos por separado, o bien compartir un entorno variable, donde los proyectos podrían influir entre sí dependiendo de la versión de las bibliotecas.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Herramientas. ¿Qué utilizamos?

  • El propio Docker. En el Dockerfile se describen las dependencias de una aplicación.
  • Docker-compose es una unión que combina varias de nuestras aplicaciones Docker.
  • Usamos GitLab para almacenar el código fuente.
  • GitLab-CI lo utilizamos para la integración continua.

Proceso de desarrollo y prueba con Docker y Gitlab CI

La presentación consta de dos partes.

La primera parte hablará sobre cómo ejecutamos Docker en las máquinas de los desarrolladores.

La segunda parte hablará sobre cómo interactuar con GitLab, cómo ejecutamos pruebas y cómo implementamos en Staging.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Docker es una tecnología que permite, utilizando un enfoque declarativo, describir los componentes necesarios. Este es un ejemplo de Dockerfile. Aquí anunciamos que heredamos de la imagen oficial de Docker Ruby:2.3.0. Contiene Ruby versión 2.3 instalado. Instalamos las bibliotecas necesarias para la construcción y NodeJS. Describimos que creamos un directorio. /appDesignamos el directorio app como el directorio de trabajo. En este directorio colocamos un Gemfile y Gemfile.lock mínimos necesarios. Luego, ejecutamos la construcción de proyectos, que instala las dependencias de esta imagen. Indicamos que el contenedor estará listo para escuchar en el puerto externo 3000. El último comando es el que inicia nuestra aplicación. Si ejecutamos el comando para iniciar el proyecto, la aplicación intentará ejecutarse y lanzará el comando indicado.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Este es un ejemplo mínimo de un archivo docker-compose. En este caso, mostramos cómo se conectan dos contenedores: el servicio de base de datos y el servicio web. Nuestras aplicaciones web, en la mayoría de los casos, requieren algún tipo de base de datos como backend para el almacenamiento de datos. En este caso, usamos MySQL, así que el ejemplo es con MySQL, pero no hay nada que impida usar otra base de datos (PostgreSQL, Redis).

Tomamos de la fuente oficial en Docker Hub la imagen de MySQL 5.7.14 sin cambios. La imagen que representa nuestra aplicación web la construimos desde el directorio actual. Durante el primer lanzamiento, se genera nuestra imagen. Después, ejecuta el comando que aquí realizamos. Si volvemos atrás, notaremos que se definió un comando de lanzamiento a través de Puma. Puma es un servicio escrito en Ruby. En el segundo caso, lo sobrescribimos. Este comando puede ser arbitrario dependiendo de nuestras necesidades o tareas.

También describimos que hay que redirigir el puerto de nuestra máquina host de desarrollador del 3000 al puerto 3000 del contenedor. Esto se realiza automáticamente mediante iptables y su mecanismo integrado en Docker.

El desarrollador también puede, como antes, dirigirse a cualquier dirección IP disponible, por ejemplo, 127.0.0.1 local o la dirección IP externa de la máquina.

La última línea indica que el contenedor web depende del contenedor db. Cuando llamamos al lanzamiento del contenedor web, previamente docker-compose iniciará nuestra base de datos. Tras el inicio de la base de datos (de hecho, después de iniciar el contenedor. ¡No garantiza la disponibilidad de la BBDD!) se iniciará nuestra aplicación, nuestro backend.

Esto permite evitar errores cuando la base de datos no está activa y ayuda a ahorrar recursos cuando detenemos el contenedor de la base de datos, liberando así recursos para otros proyectos.

Proceso de desarrollo y prueba con Docker y Gitlab CI

El uso de la contenedorización de la base de datos en el proyecto nos proporciona una versión fija de MySQL para todos los desarrolladores. Esto ayuda a evitar ciertos errores que pueden surgir debido a discrepancias entre versiones, cuando cambian la sintaxis, la configuración y los valores predeterminados. Permite especificar nombres de host comunes para la base de datos, el inicio de sesión y la contraseña. Nos alejamos de la confusión de nombres y conflictos en los archivos de configuración que existían anteriormente.

Tenemos la posibilidad de utilizar una configuración más óptima para el entorno de desarrollo, que será diferente de la predeterminada. MySQL, por defecto, está configurado para máquinas de bajo rendimiento y su rendimiento es muy bajo de forma predeterminada.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Docker permite utilizar el intérprete de Python, Ruby, NodeJS, PHP en la versión necesaria. Nos libramos de la necesidad de usar un gestor de versiones. Anteriormente, usábamos un paquete rpm para Ruby, que permitía cambiar la versión según el proyecto. También permite, gracias al contenedor Docker, migrar el código y versionarlo junto con sus dependencias de manera fluida. No tenemos problemas para entender la versión tanto del intérprete como del código. Para actualizar la versión, es necesario eliminar el contenedor viejo y levantar un nuevo contenedor. Si algo sale mal, podemos eliminar el nuevo contenedor y levantar el viejo.

Después de construir la imagen, los contenedores serán idénticos tanto en Desarrollo como en Producción. Esto es especialmente relevante para instalaciones grandes.

Proceso de desarrollo y prueba con Docker y Gitlab CI En el Frontend usamos JavaScript y NodeJS.

Ahora, nuestro último proyecto es con ReactJS. El desarrollador ejecutó todos los contenedores y desarrolló usando hot-reload.

A continuación, se lanza la tarea para compilar JavaScript y el código compilado en estático se sirve a través de nginx, ahorrando recursos.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Aquí he presentado un esquema de nuestro último proyecto.

¿Qué problemas resolvimos? Surgió la necesidad de construir un sistema con el que interactúan dispositivos móviles. Ellos reciben datos. Una de las capacidades es enviar notificaciones push a estos dispositivos.

¿Qué hicimos para esto?

Dividimos la aplicación en componentes como: parte administrativa en JS, backend que trabaja a través de la interfaz REST bajo Ruby on Rails. El backend interactúa con la base de datos. El resultado que se genera se envía al cliente. La administración interactúa con el backend y la base de datos a través de la interfaz REST.

También tuvimos la necesidad de enviar notificaciones push. Antes, teníamos un proyecto en el que se implementó un mecanismo que se encargaba de la entrega de notificaciones en plataformas móviles.

Desarrollamos el siguiente esquema: el operador interactúa con la administración desde el navegador, la administración interactúa con el backend, se establece la tarea de enviar notificaciones push.

Las notificaciones push interactúan con otro componente, que está implementado en NodeJS.

Se construyen colas y luego el envío de notificaciones continúa de acuerdo con su propio mecanismo.

Aquí se dibujan dos bases de datos. En este momento, estamos utilizando 2 bases de datos independientes a través de Docker, que no están conectadas entre sí. Además de que comparten una red virtual, los datos físicos se almacenan en diferentes directorios en la máquina del desarrollador.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Lo mismo pero en cifras. Aquí es importante la reutilización del código.

Si antes hablábamos de la reutilización del código en forma de bibliotecas, en este ejemplo nuestro servicio que maneja las notificaciones Push se reutiliza como un servidor completo. Proporciona una API. Nuestra nueva aplicación interactúa con él.

En ese momento, utilizábamos la versión 4 de NodeJS. Ahora (en 2017 — nota del editor) en desarrollos recientes usamos la versión 7 de NodeJS. No hay problemas al atraer nuevas versiones de bibliotecas en nuevos componentes.

Si es necesario, se puede realizar una refactorización y actualizar la versión de NodeJS en el servicio de notificaciones Push.

Y si podemos mantener la compatibilidad a través de la API, entonces podemos reemplazarlo en otros proyectos que se usaron anteriormente.

Proceso de desarrollo y prueba con Docker y Gitlab CI

¿Qué se necesita para agregar Docker? Añadimos a nuestro repositorio un Dockerfile que describe las dependencias necesarias. En este ejemplo, los componentes están divididos lógicamente. Es un conjunto mínimo para un desarrollador backend.

Al crear un nuevo proyecto, creamos un Dockerfile y describimos el ecosistema necesario (Python, Ruby, NodeJS). En docker-compose se describe la dependencia necesaria: la base de datos. Indicamos que se necesita una base de cierta versión y que almacene los datos en tal lugar.

Usamos un tercer contenedor separado con nginx para servir estáticos. Se prevé la posibilidad de cargar imágenes. El backend las coloca en un volumen previamente preparado, que también está montado en el contenedor con nginx, que sirve los estáticos.

Para almacenar la configuración de nginx y mysql, añadimos una carpeta Docker, en la que guardamos las configuraciones necesarias. Cuando un desarrollador clona el repositorio en su máquina, ya recibe un proyecto listo para el desarrollo local. No hay dudas sobre qué puerto o configuraciones aplicar.

Proceso de desarrollo y prueba con Docker y Gitlab CI

A continuación, tenemos varios componentes: administración, inform-API, notificaciones push.

Para poner todo esto en marcha, hemos creado otro repositorio, al que llamamos dockerized-app. En este momento, estamos utilizando varios repositorios para cada componente. Se diferencian lógicamente: en GitLab se presenta como una carpeta, mientras que en la máquina del desarrollador es una carpeta para un proyecto específico. En un nivel inferior se encuentran los componentes que se van a integrar.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Este es un ejemplo del contenido de dockerized-app. También hemos sacado aquí el directorio Docker, donde añadimos las configuraciones necesarias para la interacción de todos los componentes. Hay un README.md que describe brevemente cómo ejecutar el proyecto.

Aquí hemos utilizado dos archivos docker-compose. Esto se hace para tener la posibilidad de iniciar de forma escalonada. Cuando un desarrollador trabaja con el núcleo, si no necesita notificaciones push, simplemente ejecuta el archivo docker-compose, lo que ahorra recursos.

Si es necesario integrar con notificaciones push, entonces se ejecutan docker-compose.yaml y docker-compose-push.yaml.

Dado que docker-compose.yaml y docker-compose-push.yaml están en la carpeta, se crea automáticamente una red virtual unificada.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Descripción de los componentes. Este es un archivo más detallado, que se encarga de compilar componentes. ¿Qué es notable aquí? Aquí introducimos el componente equilibrador.

Esta es una imagen de Docker lista, donde se ejecuta nginx y una aplicación que escucha el socket de Docker. A medida que se activan y desactivan los contenedores, se regenera dinámicamente la configuración de nginx. Nos dirigimos a los componentes a través de nombres de dominio de tercer nivel.

Para un entorno de desarrollo, utilizamos el dominio .dev — api.informer.dev. Las aplicaciones con el dominio .dev son accesibles desde la máquina local del desarrollador.

Luego, se transferirán las configuraciones a cada proyecto y se iniciarán todos los proyectos simultáneamente.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Si lo representamos gráficamente, el cliente es nuestro navegador o alguna herramienta que utilizamos para hacer solicitudes al equilibrador.

El equilibrador determina, por el nombre de dominio, a qué contenedor se debe dirigir la solicitud.

Esto puede ser nginx, que entrega JS de las interfaces administrativas, o puede ser nginx, que entrega API o archivos estáticos que son servidos por nginx en forma de carga de imágenes.

En el esquema se puede ver que los contenedores están unidos en una red virtual y están ocultos detrás de un proxy.

En la máquina del desarrollador, se puede acceder al contenedor conociendo la IP, pero en principio no lo aplicamos. Prácticamente no surge la necesidad de un acceso directo.

Proceso de desarrollo y prueba con Docker y Gitlab CI

¿Qué ejemplo ver para dockerizar mi aplicación? En mi opinión, un buen ejemplo es la imagen oficial de Docker para MySQL.

Es bastante complicada. Hay muchas versiones. Pero su funcionalidad cubre muchas necesidades que pueden surgir durante el desarrollo posterior. Si dedicas tiempo a entender cómo interactúa todo esto, creo que no tendrás problemas implementándolo por tu cuenta.

En hub.docker.com, generalmente hay enlaces a github.com, donde se encuentran los datos en bruto que se pueden utilizar para construir la imagen por sí mismo.

A continuación, en este repositorio hay un script docker-endpoint.sh, que se encarga de la inicialización inicial y del procesamiento posterior del lanzamiento de la aplicación.

También en este ejemplo hay una opción de configuración a través de variables de entorno. Al definir variables de entorno al iniciar un contenedor individual o a través de docker-compose, podemos indicar que necesitamos establecer una contraseña vacía para docker para root en MySQL o alguna otra que deseemos.

Hay una opción para crear una contraseña aleatoria. Decimos que necesitamos un usuario, que se requiere establecer una contraseña para el usuario y que necesitamos crear una base de datos.

En nuestros proyectos, unificamos un poco el Dockerfile que se encarga de la inicialización. Lo ajustamos a nuestras necesidades para simplemente extender los derechos del usuario que utiliza la aplicación. Esto permitió crear fácilmente una base de datos desde la consola de la aplicación. En aplicaciones Ruby, hay comandos para crear, modificar y eliminar bases de datos.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Este es un ejemplo de cómo se ve una versión específica de MySQL en github.com. Se puede abrir el Dockerfile y ver cómo se realiza la instalación.

docker-endpoint.sh es el script que responde por el punto de entrada. Durante la inicialización inicial, se requieren ciertas acciones de preparación y todas estas acciones se han extraído al script de inicialización.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Pasemos a la segunda parte.

Para almacenar el código fuente, hemos pasado a gitlab. Es un sistema bastante potente, que tiene una interfaz visual.

Uno de los componentes de Gitlab es Gitlab CI. Permite describir una secuencia de comandos que luego se utilizarán para organizar el sistema de entrega de código o ejecutar pruebas automáticas.

Informe sobre Gitlab CI 2 https://goo.gl/uohKjI — informe del club Ruby Russia — es bastante detallado y puede interesarte.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Ahora veremos qué se requiere para activar Gitlab CI. Para iniciar Gitlab CI, solo necesitamos colocar un archivo .gitlab-ci.yml en la raíz del proyecto.

Aquí describimos lo que queremos hacer: una secuencia de estados como pruebas y despliegues.

Ejecutamos scripts que llaman directamente a docker-compose para construir nuestra aplicación. Este es un ejemplo justamente del backend.

Luego indicamos que es necesario ejecutar las migraciones para cambiar la base de datos y realizar pruebas.

Si los scripts se ejecutan correctamente y no regresan un código de error, entonces el sistema pasa a la segunda etapa de despliegue.

La etapa de despliegue actualmente está implementada para staging. No hemos organizado reinicios sin tiempo de inactividad.

Forzamos el apagado de todos los contenedores y luego levantamos de nuevo todos los contenedores, construidos en la primera etapa durante las pruebas.

Ejecutamos las migraciones de base de datos actuales que fueron escritas por los desarrolladores.

Hay una nota que aplicar esto solo para la rama master.

No se ejecuta al cambiar otras ramas.

Hay la posibilidad de organizar despliegues por ramas.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Para organizar esto más adelante, necesitamos instalar Gitlab Runner.

Esta herramienta está escrita en Golang. Es un solo archivo, como es habitual en el mundo de Golang, que no requiere dependencias.

Al iniciar, registramos Gitlab Runner.

Obtenemos en la interfaz web de Gitlab una clave.

Luego llamamos al comando de inicialización en la línea de comandos.

Configuramos Gitlab Runner en modo diálogo (Shell, Docker, VirtualBox, SSH)

El código en Gitlab Runner se ejecutará en cada commit según la configuración de .gitlab-ci.yml.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Así es como se ve visualmente en Gitlab en la interfaz web. Después de conectar Gitlab CI, aparece una bandera que indica en qué estado está el build en ese momento.

Vemos que hace 4 minutos se realizó un commit que pasó todas las pruebas y no causó problemas.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Podemos examinar más a fondo las compilaciones. Aquí vemos que ya hemos pasado por dos estados. Estado de prueba y estado de despliegue en staging.

Si hacemos clic en una compilación específica, allí habrá una salida de consola de los comandos que se ejecutaron durante el proceso según .gitlab-ci.yml.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Así es como se ve el historial de nuestro producto. Vemos que hubo intentos exitosos. Cuando las pruebas fallan, no se avanza al siguiente paso y el código en staging no se actualiza.

Proceso de desarrollo y prueba con Docker y Gitlab CI

¿Qué problemas resolvimos en staging cuando implementamos Docker? Nuestro sistema está compuesto por componentes y surgió la necesidad de reiniciar solo una parte de los componentes que fueron actualizados en el repositorio, en lugar de todo el sistema.

Para ello, tuvimos que organizar todo en carpetas separadas.

Después de hacerlo, tuvimos un problema en que Docker-compose crea un espacio de red para cada carpeta y no ve los componentes vecinos.

Para solucionarlo, creamos una red en Docker manualmente. En Docker-compose especificamos que usara esa red para este proyecto.

Así, cada componente que se inicia con esta red puede ver componentes en otras partes del sistema.

El siguiente problema es la separación de staging entre varios proyectos.

Para que todo se vea bien y lo más parecido posible a producción, es recomendable usar los puertos 80 o 443, que se utilizan comúnmente en la WEB.

Proceso de desarrollo y prueba con Docker y Gitlab CI

¿Cómo lo resolvimos? Asignamos un Gitlab Runner a todos los grandes proyectos.

Gitlab permite ejecutar varios Gitlab Runners distribuidos, que simplemente tomarán todas las tareas de manera aleatoria y las ejecutarán.

Para evitar el caos, limitamos el grupo de nuestros proyectos a un solo Gitlab Runner, que maneja nuestras cargas sin problemas.

Movimos nginx-proxy a un script de inicio separado y especificamos las redes de todos los proyectos en él.

Nuestro proyecto tiene una red, y el balanceador tiene varias redes con nombres de proyectos. Puede dirigir el tráfico según los nombres de dominio.

Las solicitudes llegan a través del dominio en el puerto 80 y se redirigen a un grupo de contenedores que atiende ese dominio.

Proceso de desarrollo y prueba con Docker y Gitlab CI

¿Cuáles fueron otros problemas? Todos los contenedores se ejecutan por defecto como el usuario root. Este root no es el mismo root del sistema host.

Sin embargo, si ingresas al contenedor, estarás como root y el archivo que creamos en ese contenedor tiene permisos de root.

Si un desarrollador ingresó al contenedor y ejecutó comandos que generaron archivos, luego salió del contenedor, en su directorio de trabajo tiene un archivo al que no tiene acceso.

¿Cómo se puede resolver esto? Se pueden agregar usuarios que estarán en el contenedor.

¿Qué problemas surgieron cuando agregamos un usuario?

Al crear un usuario, a menudo no coinciden el ID de grupo (UID) y el ID de usuario (GID).

Para resolver este problema en el contenedor, utilizamos usuarios con ID 1000.

En nuestro caso, esto coincide con el hecho de que prácticamente todos los desarrolladores utilizan el sistema operativo Ubuntu. Y en Ubuntu, el primer usuario tiene ID 1000.

Proceso de desarrollo y prueba con Docker y Gitlab CI

¿Cuáles son nuestros planes?

Leer la documentación sobre Docker. El proyecto se está desarrollando activamente, la documentación cambia. Los datos que se obtuvieron hace dos o tres meses ya están empezando a quedar obsoletos.

Parte de los problemas que resolvimos ya podrían estar solucionados por medios estándar.

Realmente quiero avanzar y pasar directamente a la orquestación.

Uno de los ejemplos es el mecanismo integrado en Docker llamado Docker Swarm, que se ofrece de forma predeterminada. Me gustaría lanzar algo en producción basado en la tecnología de Docker Swarm.

La creación de contenedores complica el trabajo con los registros. Actualmente, los registros están aislados. Están dispersos por los contenedores. Una de las tareas es facilitar el acceso a los registros a través de una interfaz web.

Proceso de desarrollo y prueba con Docker y Gitlab CI

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster