No hace mucho escribí sobre contenerización de una API RESTful Node.js y un servidor Couchbase para demostrar lo fácil que es desplegar aplicaciones web de forma rápida y fiable. En esa guía creamos una API sencilla, construimos una imagen Docker a partir de ella, la desplegamos como contenedor y desplegamos Couchbase como contenedor. Sin embargo, entiendo que no todo el mundo está familiarizado con Node.js.
Aquí vamos a construir una sencilla API Java RESTful utilizando Spring Boot, crear una aplicación Docker y desplegarla como contenedor con Couchbase. Esto creará un entorno familiar para los desarrolladores Java.
Este tutorial requiere que tengas Docker instalado y configurado en tu máquina. Con Docker crearemos imágenes Docker personalizadas y las desplegaremos como contenedores.
Crear una imagen Docker personalizada para Couchbase Server
Empecemos creando una imagen Docker personalizada para Couchbase Server. Mientras que una imagen imagen oficial de Couchbase no se aprovisiona automáticamente cuando se despliega. Nuestra imagen personalizada se aprovisionará automáticamente al desplegarse como contenedor.
En algún lugar de tu ordenador crea un directorio con un Dockerfile y configure.sh en él. El sitio Dockerfile será el plano de nuestra imagen y el archivo configure.sh será el script de aprovisionamiento que se ejecute cuando se despliegue el contenedor.
Abra el configure.sh e incluya lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
set -m /entrypoint.sh couchbase-server & dormir 15 curl -v -X POST http://127.0.0.1:8091/pools/default -d memoryQuota=512 -d indexMemoryQuota=512 curl -v http://127.0.0.1:8091/node/controller/setupServices -d services=kv%2cn1ql%2Cindex curl -v http://127.0.0.1:8091/settings/web -d port=8091 -d username=$COUCHBASE_ADMINISTRATOR_USERNAME -d password=$COUCHBASE_ADMINISTRATOR_PASSWORD curl -i -u $COUCHBASE_ADMINISTRATOR_USERNAME:$COUCHBASE_ADMINISTRATOR_PASSWORD -X POST http://127.0.0.1:8091/settings/indexes -d 'storageMode=memory_optimized' curl -v -u $COUCHBASE_ADMINISTRATOR_USERNAME:$COUCHBASE_ADMINISTRATOR_PASSWORD -X POST http://127.0.0.1:8091/pools/default/buckets -d name=$COUCHBASE_BUCKET -d bucketType=couchbase -d ramQuotaMB=128 -d authType=sasl -d saslPassword=$COUCHBASE_BUCKET_PASSWORD dormir 15 curl -v http://127.0.0.1:8093/query/service -d "statement=CREATE PRIMARY INDEX ON `$COUCHBASE_BUCKET`" fg 1 |
Couchbase puede ser configurado a través de HTTP después de ser desplegado. Nuestro script de configuración especificará recursos de instancia, credenciales administrativas, un Bucket y un índice primario. Verás que se utilizan una serie de variables como $COUCHBASE_NOMBRE_DE_USUARIO_ADMINISTRATIVO
y $COUCHBASE_BUCKET
. Estos datos pueden introducirse en tiempo de ejecución para evitar que tengamos que codificar información sensible.
Más información sobre el aprovisionamiento de un contenedor Couchbase a través de HTTP puede verse en un artículo anterior que escribí sobre el tema.
Con el script de aprovisionamiento completo, tenemos que terminar el Dockerfile . Ábralo e incluya lo siguiente:
1 2 3 4 5 |
DESDE couchbase COPIAR configure.sh /opt/couchbase CMD ["/opt/couchbase/configure.sh"] |
La imagen Docker personalizada utilizará la imagen Docker oficial como base, copiará nuestro script de aprovisionamiento durante el proceso de compilación y lo ejecutará en tiempo de ejecución.
Para crear la imagen personalizada para Couchbase, ejecute lo siguiente:
1 |
docker build -t couchbase-custom /ruta/a/directorio/con/dockerfile |
En el comando anterior couchbase-personalizar
es el nombre de la imagen y se construye a partir de la ruta que contiene el archivo Dockerfile archivo.
Desarrollo de una API RESTful de Spring Boot con Java
Antes de que podamos contenerizar nuestra aplicación Java tenemos que construirla. Como estamos utilizando Spring Boot, tenemos que descargar un proyecto de inicio. Esto se puede hacer fácilmente desde la página Inicialización de muelles sitio web.
Para este proyecto estoy utilizando com.couchbase
como mi grupo y docker
como mi artefacto. También prefiero Gradle, así que estoy usando eso en lugar de Maven.
Extraiga el proyecto descargado y abra el archivo src/main/resources/application.properties archivo. En este archivo incluya lo siguiente:
1 2 3 |
couchbase_host=couchbase couchbase_bucket=default couchbase_bucket_password= contraseña |
En lo anterior estamos asumiendo que nuestra instancia host se llama couchbase
y tiene un Bucket sin contraseña llamado por defecto
. Si estuvieras probando localmente, el host probablemente sería localhost. En cualquier caso, todas estas propiedades van a ser definidas en tiempo de ejecución del contenedor a través de variables de entorno.
Ahora abra el proyecto src/main/java/com/couchbase/DockerApplication.java archivo. Aquí vamos a cargar nuestras propiedades y definir nuestros endpoints. Abra este archivo e incluya el siguiente código Java:
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 |
paquete com.couchbase; import com.couchbase.client.java.Bucket; import com.couchbase.client.java.Cluster; import com.couchbase.client.java.CouchbaseCluster; import com.couchbase.client.java.query.*; import com.couchbase.client.java.query.consistency.ScanConsistency; import com.couchbase.client.java.document.json.JsonObject; import com.couchbase.client.java.document.JsonDocument; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.*; import org.springframework.context.annotation.*; import org.springframework.http.*; import org.springframework.web.bind.annotation.*; import javax.servlet.*; import javax.servlet.http.HttpServletResponse; import java.util.*; import java.util.concurrent.TimeUnit; @SpringBootApplication @RestController @RequestMapping("/") public class DockerApplication { @Valor("${couchbase_host}") privado String hostname; @Valor("${couchbase_bucket}") privado String bucket; @Valor("${contrase_de_cubo_couchbase}") privado String password; público @Bean Cluster cluster() { return CouchbaseCluster.create(nombredehost); } público @Bean Cubo bucket() { return cluster().openBucket(bucket, password); } @RequestMapping(value="/", method= RequestMethod.GET) public String raíz() { return "Intenta visitar los puntos finales `/get` o `/save`"; } @RequestMapping(value="/get", method= RequestMethod.GET) public Object get() { String query = "SELECT `" + bucket().name() + "`.* FROM `" + bucket().name() + "`"; return bucket().async().query(N1qlQuery.simple(query, N1qlParams.build().consistency(ScanConsistency.REQUEST_PLUS))) .flatMap(AsyncN1qlQueryResult::rows) .map(resultado -> resultado.valor().toMap()) .toList() .timeout(10, TimeUnit.SECONDS) .toBlocking() .single(); } @RequestMapping(value="/guardar", method=MétodoRequest.POST) public Object guardar(@RequestBody String json) { JsonObject jsonData = JsonObject.fromJson(json); JsonDocument document = JsonDocument.create(UUID.randomUUID().toString(), jsonData); bucket().insert(document); return new ResponseEntity(json, HttpStatus.OK); } public static void main(String[] args) { SpringApplication.run(DockerApplication.class, args); } } |
En lo anterior no ocurren demasiadas cosas. Gran parte es código repetitivo y declaraciones de importación. Como el objetivo de este artículo no es usar Java con Couchbase, no explicaré cada parte del código. En su lugar, debes saber que tiene tres puntos finales, uno de los cuales obtendrá todos los documentos en el Bucket y uno de los cuales guardará nuevos documentos en Couchbase.
Si usas Gradle como yo, tienes que cambiar la directiva build.gradle archivo. Necesita tener una tarea creada y dependencias añadidas. Su build.gradle debería tener este aspecto:
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 |
buildscript { ext { springBootVersion = '1.5.2.RELEASE' } repositorios { mavenCentral() } dependencias { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } aplicar plugin: 'java' aplicar plugin: 'eclipse' aplicar plugin: 'org.springframework.boot' versión = '0.0.1-SNAPSHOT' fuenteCompatibilidad = 1.8 repositorios { mavenCentral() } dependencias { compilar('org.springframework.boot:spring-boot-starter-web') compilar('org.springframework:spring-tx') compilar('org.springframework.security:spring-security-core') compilar('com.couchbase.client:java-client') testCompile('org.springframework.boot:spring-boot-starter-test') } task(run, dependsOn: 'classes', type: JavaExec) { main = 'com.couchbase.DockerApplication' classpath = sourceSets.main.runtimeClasspath } |
Para construir la aplicación, ejecute lo siguiente:
1 |
gradle build -x test |
Ahora tendrás un archivo JAR para ser utilizado en nuestra imagen Docker.
Creación de una imagen Docker personalizada para la aplicación Spring Boot
Construir una imagen personalizada requerirá que tengamos un Dockerfile en su lugar. En la base de su proyecto Java, añada un archivo Dockerfile e incluya lo siguiente:
1 2 3 4 5 |
DE openjdk:8 COPIAR ./build/libs/java-project-0.0.1-SNAPSHOT.jar spring-boot.jar CMD java -jar spring-boot.jar |
En el ejemplo anterior estamos usando la imagen oficial de OpenJDK como base y estamos copiando nuestro JAR en la imagen en tiempo de compilación. En el despliegue, el JAR se ejecuta.
Para construir esta imagen, ejecute lo siguiente:
1 |
docker build -t spring-boot-custom /ruta/a/directorio/con/dockerfile |
El comando anterior debería resultarte familiar. Estamos creando un spring-boot-custom
utilizando el plano que se encuentra en el directorio de nuestro Dockerfile archivo.
Para obtener más información sobre la creación de imágenes Docker personalizadas, puede visitar un artículo anterior que escribí llamado, Cree una imagen Docker personalizada para su aplicación web en contenedores.
Despliegue de las imágenes de Couchbase y Spring Boot como contenedores
Hay varias opciones a la hora de desplegar nuestras imágenes. Podemos utilizar un archivo Compose o desplegarlos como contenedores vainilla. Me parece que Compose es un enfoque más limpio, así que lo usaremos.
En algún lugar de tu ordenador crea un docker-compose.yml e incluya lo siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
versión: "2 servicios: couchbase: imagen: couchbase-custom puertos: - 8091:8091 - 8092:8092 - 8093:8093 medio ambiente: - COUCHBASE_ADMINISTRATOR_USERNAME=Administrador - COUCHBASE_ADMINISTRATOR_PASSWORD=contraseña - COUCHBASE_BUCKET=por defecto - COUCHBASE_BUCKET_PASSWORD= CONTRASEÑA bota de resorte: imagen: spring-boot-custom puertos: - 8080:8080 medio ambiente: - COUCHBASE_HOST=couchbase - COUCHBASE_BUCKET=por defecto - COUCHBASE_BUCKET_PASSWORD= CONTRASEÑA reinicio: siempre |
En el archivo anterior estamos definiendo las imágenes personalizadas que construimos y estamos haciendo el mapeo de puertos a la máquina anfitriona. Lo que es particularmente interesante es el medio ambiente
opciones. Éstas coinciden con las variables que tenemos en nuestro aplicación.propiedades y configure.sh archivos.
Para desplegar nuestros contenedores con Compose, ejecuta lo siguiente:
1 2 |
docker-compose run -d --service-ports --name couchbase couchbase docker-compose run -d --service-ports --name spring-boot spring-boot |
Algo a tener en cuenta sobre los comandos anteriores. Couchbase no se despliega instantáneamente. Tendrás que esperar hasta que esté completamente desplegado antes de desplegar la aplicación Java. Después de lanzar ambas aplicaciones, compruébalas navegando a la aplicación Java en tu navegador web.
Conclusión
Acaba de ver cómo crear Docker para una aplicación Spring Boot y un servidor Couchbase. Después de desplegar cada uno como contenedores serán capaces de comunicarse entre sí lo que es increíblemente conveniente para el mantenimiento.
Si te interesa ver cómo se hace esto con Node.js, echa un vistazo a la página artículo anterior que escribí sobre el tema. Si estás interesado en aprender más sobre el Java SDK para Couchbase, echa un vistazo al Portal para desarrolladores de Couchbase.
[...] te interesa, puedes echar un vistazo a Usar Docker para desplegar una aplicación web Java con Couchbase en contenedores y Desplegar una aplicación web Node.js con Couchbase como contenedores Docker, según [...]