Ratnopam Chakrabarti es un desarrollador de software que trabaja actualmente para Ericsson Inc. Lleva bastante tiempo centrado en IoT, tecnologías máquina a máquina, coches conectados y dominios de ciudades inteligentes. Le encanta aprender nuevas tecnologías y ponerlas en práctica. Cuando no está trabajando, le gusta pasar tiempo con su hijo de 3 años.
Introducción
Bienvenido a la segunda parte de la serie en la que describo cómo desarrollar y ejecutar una aplicación web Spring Boot totalmente funcional y potenciada por Couchbase utilizando el conjunto de herramientas Docker. En primera parte de la serie, demostré cómo ejecutar dos contenedores Docker para ejecutar una aplicación funcional con una interfaz de usuario presentable. Los dos contenedores Docker que estábamos ejecutando son:
- A Contenedor Couchbase con ajustes preconfigurados
- Un contenedor de aplicación hablando con el contenedor Couchbase (Ejecutado en el paso 1)
Aunque este método es útil, no está totalmente automatizado, es decir, no existe la orquestación automatizada. Tienes que ejecutar dos comandos de ejecución de Docker diferentes para ejecutar toda la configuración.
¿Hay alguna forma de construir y ejecutar el contenedor de la aplicación que también active la ejecución del contenedor de Couchbase? Por supuesto que hay una manera.
Entrar en Docker Compose
Utilizando Docker Composepuedes orquestar la ejecución de entornos multicontenedor, que es exactamente lo que necesitamos para nuestro caso de uso. Necesitamos ejecutar el contenedor Couchbase primero, y luego el contenedor de la aplicación debe ejecutarse y hablar con el contenedor Couchbase.
Aquí está el archivo docker-compose.yml para lograr esto:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
versión: "2" servicios: aplicación: construya: . puertos: - 8080:8080 medio ambiente: - NOMBRE_CUBO=libros - ANFITRIÓN=192.168.99.100 depende_de: - db db: imagen: chakrar27/couchbase:libros puertos: - 8091:8091 - 8092:8092 - 8093:8093 - 8094:8094 - 11210:11210 |
Nuestra app "depende_de" la imagen db que es el contenedor Couchbase. En otras palabras, el contenedor Couchbase se ejecuta primero y luego el contenedor de la aplicación. Hay un problema potencial aquí: la palabra clave "depends_on" no garantiza que el contenedor Couchbase haya terminado de configurar la imagen y haya empezado a ejecutarse. Todo lo que asegura es que el contenedor se inicie primero; no comprueba si el contenedor está realmente ejecutándose o listo para aceptar peticiones de una aplicación. Para asegurarnos de que el contenedor de Couchbase se está ejecutando y que todos los pasos de preconfiguración, como la configuración de la consulta, los servicios de índice y el bucket, se han completado, necesitamos hacer una comprobación desde el contenedor de la aplicación.
Este es el Dockerfile del contenedor de la aplicación que invoca un script que, a su vez, comprueba si el bucket "books" ya ha sido configurado o no. Entra en un bucle hasta que el bucket está configurado y entonces activa el contenedor de la aplicación.
https://github.com/ratchakr/bookstoreapp/blob/master/Dockerfile-v1
El guión puede verse en https://github.com/ratchakr/bookstoreapp/blob/master/run_app.sh
El script hace lo siguiente
Utiliza el endpoint REST soportado por Couchbase para consultar el bucket.
Curl se utiliza para llamar a los puntos finales REST. La instalación de curl está cubierta en el Dockerfile de la aplicación.
El script analiza la respuesta JSON de la llamada REST utilizando una herramienta llamada jq.
Si el cubo está configurado, ejecuta el contenedor de aplicaciones; de lo contrario, espera a que el cubo se configure primero.
Vale la pena mencionar que se pueden añadir más comprobaciones, como verificar si el servicio de índice y el servicio de consulta están configurados correctamente o no, en el script de shell para hacerlo más robusto. Una palabra de precaución es confirmar tu caso de uso particular y los requisitos antes de seguir el enfoque docker-compose; no hay una manera segura de determinar si el contenedor db Couchbase está completamente en marcha y listo para servir peticiones de la aplicación cliente. Algunos de los enfoques que podrían funcionar son los siguientes:
- Si dispone de un bucket preconfigurado, puede comprobar si el bucket existe
- Compruebe si los índices están en su sitio
- Si conoce el recuento de registros de un bucket (digamos que de un archivo .csv que se ha importado a un bucket en el momento de la carga inicial de datos), puede comprobar si el recuento coincide con el número de registros del archivo .csv). Para nuestro caso de uso, el mencionado anteriormente funciona bien.
Construir y ejecutar
Ahora que tenemos nuestro archivo docker-compose y Dockerfile, podemos construir la imagen de la aplicación mediante el simple comando docker-compose up mando.
Aquí está el fragmento de salida de la consola Docker:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
$ docker-componer arriba Creación de red "bookstoreapp_default" con el por defecto conductor Tirando de db (chakrar27/couchbase:libros)... libros: Tirando de de chakrar27/couchbase Digerir: sha256:4bc356a1f2b5b3d7ee3daf10cd5c55480ab831a0a147b07f5b14bea3de909fd9 Estado: Descargado más nuevo imagen para chakrar27/couchbase:libros Edificio aplicación Paso 1/8 : DESDE frolvlad/alpino-oraclejdk8:completo completo: Tirando de de frolvlad/alpino-oraclejdk8 Digerir: sha256:a344745faa77a9aa5229f26bc4f5c596d13bcfc8fcac051a701b104a469aff1f Estado: Descargado más nuevo imagen para frolvlad/alpino-oraclejdk8:completo ---> 5f7037acb78d Paso 2/8 : VOLUMEN /tmp ---> Ejecutar en 7d18e0b90bfd ---> 6a43ccb712dc Eliminación de intermedio contenedor 7d18e0b90bfd Paso 3/8 : AÑADE objetivo/librería-1.0.0-SNAPSHOT.tarro aplicación.tarro ---> a3b4bf7745e0 Eliminación de intermedio contenedor 0404f1d094d3 Paso 4/8 : RUN sh -c 'touch /app.jar' ---> Ejecutar en 64d1c82a0694 ---> 1ec5a68cafa9 Eliminación de intermedio contenedor 64d1c82a0694 Paso 5/8 : RUN apk actualización && apk añada rizo ---> Ejecutar en 1f912e8341bd buscar https://dl-cdn.alpinelinux.org/alpine/v3.5/main/x86_64/APKINDEX.tar.gz buscar https://dl-cdn.alpinelinux.org/alpine/v3.5/community/x86_64/APKINDEX.tar.gz v3.5.2-16-g53ad101cf8 [https://dl-cdn.alpinelinux.org/alpine/v3.5/main] v3.5.2-14-gd7ba0e189f [https://dl-cdn.alpinelinux.org/alpine/v3.5/community]. OK: 7961 distinto paquetes disponible (1/4) Instalación de ca-certificados (20161130-r1) (2/4) Instalación de libssh2 (1.7.0-r2) (3/4) Instalación de libcurl (7.52.1-r2) (4/4) Instalación de rizo (7.52.1-r2) Ejecutar busybox-1.25.1-r0.desencadenar Ejecutar ca-certificados-20161130-r1.desencadenar Ejecutar glibc-papelera-2.25-r0.desencadenar OK: 12 MiB en 18 paquetes ---> 8f99863af926 Eliminación de intermedio contenedor 1f912e8341bd Paso 6/8 : AÑADE ejecutar_app.sh . ---> cedb8d545070 Eliminación de intermedio contenedor 8af5ac3ab0a0 Paso 7/8 : RUN chmod +x ejecutar_app.sh ---> Ejecutar en 74a141de2f52 ---> 77ffd7425bea Eliminación de intermedio contenedor 74a141de2f52 Paso 8/8 : CMD sh ejecutar_app.sh ---> Ejecutar en 6f81c8ebaa37 ---> 56a3659005ef Eliminación de intermedio contenedor 6f81c8ebaa37 Con éxito construido 56a3659005ef Imagen para servicio aplicación fue construido porque it hizo no ya existe. A reconstruir este imagen usted debe utilice `docker-componer construya` o `docker-componer arriba --construya`. Creación de libreríaapp_db_1 Creación de libreríaapp_app_1 Adjuntar a libreríaapp_db_1, libreríaapp_app_1 db_1 | docker host ip = 192.168.99.100 db_1 | para dormir... aplicación_1 | Inicio aplicación ejecute script........... aplicación_1 | couchbase es corriendo en 192.168.99.100 aplicación_1 | cubo a consulte es libros db_1 | < Fecha: Vie, 24 Mar 2017 06:53:00 GMT db_1 | < Contenido-Longitud: 0 db_1 | < Caché-Controlar: no-caché db_1 | < 100 55 0 0 100 55 0 827 --:--:-- --:--:-- --:--:-- 833 db_1 | * Conexión #0 al host 127.0.0.1 intacto db_1 | cubo configure arriba hecho aplicación_1 | respuesta de cb aplicación_1 | ************************************************ aplicación_1 | ************************************************ aplicación_1 | respuesta de cb libros aplicación_1 | ************************************************ aplicación_1 | ************************************************ aplicación_1 | cubo es ahora listo cubo nombre libros aplicación_1 | Ejecutar aplicación contenedor ahora aplicación_1 | ************************************************ aplicación_1 | aplicación_1 | . ____ _ __ _ _ aplicación_1 | /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ app_1 | ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ aplicación_1 | \\/ ___)| |_)| | | | | || (_| | ) ) ) ) aplicación_1 | ' |____| .__|_| |_|_| |_\__, | / / / / app_1 | =========|_|==============|___/=/_/_/_/ app_1 :: Spring Boot :: (v1.4.2.RELEASE) app_1 | app_1 | 2017-03-24 06:53:59.839 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Book Details = Libro [id=06bad9c4-85fc-4c0b-83a7-ad21b2fdd405, title=El Irlandés Inmortal, author=Timothy Egan, isbn=ISBN444, category=Historia]. app_1 | 2017-03-24 06:53:59.839 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Detalles del libro = Libro [id=328eaf44-edff-43c6-9f55-62d7e095256d, title=El corredor de la cometa, author=Khaled Hosseini, isbn=ISBN663, category=Ficción]. app_1 | 2017-03-24 06:53:59.839 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Detalles del libro = Libro [id=56882f5a-d466-457f-82c1-1c3bca0c6d75, title=Breaking Blue, author=Timothy Egan, isbn=ISBN777, category=Thriller]. app_1 | 2017-03-24 06:53:59.839 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Book Details = Libro [id=845a2fe8-cbbf-4780-b216-41abf86d7d61, title=Historia de la Humanidad, author=Gabriel Garcia, isbn=ISBN123, category=Historia]. app_1 | 2017-03-24 06:53:59.840 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Detalles del libro = Libro [id=9d2833c3-e005-4c4f-98f9-75b69bbb7bf5, title=El jardinero nocturno, author=Eric Fan, isbn=ISBN333, category=Libros infantiles]. app_1 | 2017-03-24 06:53:59.840 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Book Details = Libro [id=5756bf4d-551c-429e-8bc3-2339dc065ff8, title=Grit: El poder de la pasión y la perseverancia, author=Angela Duckworth, isbn=ISBN555, category=Negocios] app_1 | 2017-03-24 06:53:59.840 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Detalles del libro = Libro [id=e8e34f30-6fdf-4ca7-9cef-e06f504f8778, title=Guerra y trementina, author=Stefan Hertmans, isbn=ISBN222, category=Ficción]. app_1 | 2017-03-24 06:54:00.234 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Libros de Timothy Egan = Libro [id=06bad9c4-85fc-4c0b-83a7-ad21b2fdd405, title=El irlandés inmortal, author=Timothy Egan, isbn=ISBN444, category=Historia]. app_1 | 2017-03-24 06:54:00.238 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Libros de Timothy Egan = Libro [id=56882f5a-d466-457f-82c1-1c3bca0c6d75, title=Breaking Blue, author=Timothy Egan, isbn=ISBN777, category=Thriller]. app_1 | 2017-03-24 06:54:00.346 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Book Starting with title 'En' = Libro [id=06bad9c4-85fc-4c0b-83a7-ad21b2fdd405, title=El irlandés inmortal, author=Timothy Egan, isbn=ISBN444, category=Historia]. app_1 | 2017-03-24 06:54:00.349 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Book Starting with title 'En' = Libro [id=328eaf44-edff-43c6-9f55-62d7e095256d, title=El corredor de la cometa, author=Khaled Hosseini, isbn=ISBN663, category=Ficción]. app_1 | 2017-03-24 06:54:00.349 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Book Starting with title 'En' = Libro [id=9d2833c3-e005-4c4f-98f9-75b69bbb7bf5, title=El jardinero nocturno, author=Eric Fan, isbn=ISBN333, category=Libros infantiles] app_1 | 2017-03-24 06:54:00.443 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Libro en Ficción = Libro [id=328eaf44-edff-43c6-9f55-62d7e095256d, title=El Corredor de la Cometa, author=Khaled Hosseini, isbn=ISBN663, category=Ficción]. app_1 | 2017-03-24 06:54:00.453 INFO 31 --- [ main] c.chakrar.sample.books.BookStoreRunner : Libro en Ficción = Libro [id=e8e34f30-6fdf-4ca7-9cef-e06f504f8778, title=Guerra y trementina, author=Stefan Hertmans, isbn=ISBN222, category=Ficción]. app_1 | 2017-03-24 06:54:02.745 INFO 31 --- [nio-8080-exec-1] o.v.spring.servlet.Vaadin4SpringServlet : Could not find a SystemMessagesProvider in the application context, using default app_1 | 2017-03-24 06:54:02.753 INFO 31 --- [nio-8080-exec-1] o.v.spring.servlet.Vaadin4SpringServlet : Inicialización personalizada del servlet Vaadin4Spring completada. app_1 | 2017-03-24 06:54:02.864 INFO 31 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring FrameworkServlet 'dispatcherServlet' app_1 | 2017-03-24 06:54:02.865 INFO 31 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : FrameworkServlet 'dispatcherServlet': inicialización iniciado |
En este punto, nuestra aplicación está en funcionamiento con un único comando de orquestación docker-compose.
Tipo 192.168.99.100:8080 en el navegador; debería ver la siguiente pantalla:

Docker Compose es una buena forma de orquestar entornos Docker multicontenedor. Tiene cadenas de comandos casi similares a los conjuntos de comandos "docker". Por ejemplo, para ver una lista de contenedores en ejecución, simplemente escriba:
docker-compose ps > que le daría
|
1 2 3 4 5 6 7 8 9 |
$ docker-componer ps Nombre Comando Estado Puertos --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- libreríaapp_app_1 /papelera/sh -c sh ejecutar_app.sh Arriba 0.0.0.0:8080->8080/tcp libreríaapp_db_1 /punto de entrada.sh /op/couchb ... Arriba 11207/tcp, 0.0.0.0:11210->11210/tcp, 11211/tcp, 18091/tcp, 18092/tcp, 18093/tcp, 0.0.0.0:8091->8091/tcp, 0.0.0.0:8092->8092/tcp, 0.0.0.0:8093->8093/tcp, 0.0.0.0:8094->8094/tcp |
Los nombres de los contenedores aparecen aquí en negrita.
Si necesita detener o desmantelar su entorno orquestado con Docker Compose, puede hacerlo con el comando docker-compose down como se muestra a continuación:
Una ejecución de muestra produce:
|
1 2 3 4 5 6 7 8 9 10 11 |
$ docker-componer abajo Detener libreríaapp_app_1 ... hecho Detener libreríaapp_db_1 ... hecho Eliminación de libreríaapp_app_1 ... hecho Eliminación de libreríaapp_db_1 ... hecho Eliminación de red bookstoreapp_default |
Ahora, si haces un docker-compose ps, muestra que ningún contenedor se está ejecutando actualmente.
|
1 2 3 4 5 |
$ docker-componer ps Nombre Comando Estado Puertos --------------------------------------------------------------- |
También puede utilizar Docker compose para un entorno de pruebas automatizado en el que se encienden los contenedores Docker, se ejecutan las pruebas y, a continuación, se desmonta toda la infraestructura, todo ello con Compose. Para obtener una descripción detallada de Docker compose, visite la página sitio web oficial.
Este post forma parte del Programa de Escritura de la Comunidad Couchbase