Não faz muito tempo, escrevi sobre Containerização de uma API RESTful do Node.js e do servidor Couchbase para demonstrar como é fácil implantar aplicativos da Web de forma rápida e confiável. Nesse guia, criamos uma API simples, construímos uma imagem do Docker a partir dela, implantamos como um contêiner e implantamos o Couchbase como um contêiner. No entanto, sei que nem todos estão familiarizados com o Node.js.
Aqui, vamos criar uma API RESTful Java simples usando o Spring Boot, criar um Docker a partir dela e implantá-la como um contêiner com Couchbase. Isso criará um ambiente familiar para os desenvolvedores Java.
Este tutorial exige que você tenha um Docker instalado e configurado em seu computador. Com o Docker, criaremos imagens personalizadas do Docker e as implantaremos como contêineres.
Criar uma imagem do Docker personalizada para o Couchbase Server
Vamos começar criando uma imagem Docker personalizada para o Couchbase Server. Embora uma imagem imagem oficial do Couchbase existe, ela não é provisionada automaticamente quando implantada. Nossa imagem personalizada será provisionada automaticamente após a implementação como um contêiner.
Em algum lugar de seu computador, crie um diretório com o nome Dockerfile arquivo e configure.sh nele. O arquivo Dockerfile será o modelo para nossa imagem e o arquivo configure.sh será o script de provisionamento que será executado quando o contêiner for implantado.
Abra o configure.sh e inclua o seguinte:
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 |
O Couchbase pode ser configurado por HTTP após a implantação. Nosso script de configuração especificará os recursos da instância, as credenciais administrativas, um Bucket e um índice primário. Você notará que diversas variáveis são usadas, como $COUCHBASE_ADMINISTRATIVE_USERNAME
e $COUCHBASE_BUCKET
. Elas podem ser passadas em tempo de execução, evitando que tenhamos que codificar informações confidenciais.
Mais informações sobre o provisionamento de um contêiner do Couchbase via HTTP podem ser vistas em um Artigo anterior que escrevi sobre o assunto.
Com o script de provisionamento concluído, temos que terminar o script Dockerfile arquivo. Abra-o e inclua o seguinte:
1 2 3 4 5 |
DE couchbase COPIAR configure.sh /opt/couchbase CMD ["/opt/couchbase/configure.sh"] |
A imagem personalizada do Docker usará a imagem oficial do Docker como base, copiará nosso script de provisionamento durante o processo de compilação e o executará em tempo de execução.
Para criar a imagem personalizada para o Couchbase, execute o seguinte:
1 |
docker build -t couchbase-custom /path/to/directory/with/dockerfile |
No comando acima couchbase-custom
é o nome da imagem e é criado a partir do caminho que contém o Dockerfile arquivo.
Desenvolvimento de uma API RESTful do Spring Boot com Java
Antes de podermos colocar nosso aplicativo Java em um contêiner, precisamos criá-lo. Como estamos usando o Spring Boot, precisamos fazer download de um projeto inicial. Isso pode ser feito facilmente na seção Inicialização do Spring site.
Para este projeto, estou usando com.couchbase
como meu grupo e doca
como meu artefato. Também prefiro o Gradle, portanto, estou usando-o em vez do Maven.
Extraia o projeto baixado e abra o arquivo src/main/resources/application.properties arquivo. Nesse arquivo, inclua o seguinte:
1 2 3 |
couchbase_host=couchbase couchbase_bucket=default couchbase_bucket_password= |
No exemplo acima, estamos assumindo que nossa instância de host se chama couchbase
e tem um Bucket sem senha chamado padrão
. Se você estivesse testando localmente, o host provavelmente seria localhost. De qualquer forma, todas essas propriedades serão definidas no tempo de execução do contêiner por meio de variáveis de ambiente.
Agora, abra o arquivo src/main/java/com/couchbase/DockerApplication.java arquivo. Aqui, carregaremos nossas propriedades e definiremos nossos pontos de extremidade. Abra esse arquivo e inclua o seguinte 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 |
pacote 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; importar org.springframework.beans.factory.annotation.Value; importar org.springframework.boot.SpringApplication; importar org.springframework.boot.autoconfigure.*; importar org.springframework.context.annotation.*; importar org.springframework.http.*; importar org.springframework.web.bind.annotation.*; importar javax.servlet.*; importar javax.servlet.http.HttpServletResponse; importar java.util.*; importar java.util.concurrent.TimeUnit; @SpringBootApplication @RestController @RequestMapping("/") classe pública DockerApplication { @Value("${couchbase_host}") private String hostname; @Value("${couchbase_bucket}") private String bucket; @Value("${couchbase_bucket_password}") private String password; público @Bean Cluster cluster() { return CouchbaseCluster.create(hostname); } público @Bean Balde() { return cluster().openBucket(bucket, password); } @RequestMapping(value="/", method= RequestMethod.GET) public String root() { return "Tente visitar os pontos de extremidade `/get` ou `/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(result -> result.value().toMap()) .toList() .timeout(10, TimeUnit.SECONDS) .toBlocking() .single(); } @RequestMapping(value="/save", method=RequestMethod.POST) public Object save(@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); } } |
Não está acontecendo muita coisa no trecho acima. Grande parte é código padrão e declarações de importação. Como o objetivo deste artigo não é usar Java com o Couchbase, não explicarei cada parte do código. Em vez disso, saiba que ele tem três pontos de extremidade, um dos quais obterá todos os documentos no Bucket e um dos quais salvará novos documentos no Couchbase.
Se você estiver usando o Gradle, como eu, precisará alterar o build.gradle arquivo. Ele precisa ter uma tarefa criada e dependências adicionadas. Suas build.gradle O arquivo deve ter a seguinte aparência:
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' } repositórios { mavenCentral() } dependências { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } aplicar o plugin: 'java' aplicar o plugin: 'eclipse' aplicar plugin: 'org.springframework.boot' versão = '0.0.1-SNAPSHOT' sourceCompatibility = 1.8 repositórios { mavenCentral() } dependências { 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) { principal = 'com.couchbase.DockerApplication' classpath = sourceSets.main.runtimeClasspath } |
Para criar o aplicativo, execute o seguinte:
1 |
gradle build -x test |
Agora você terá um arquivo JAR para ser usado em nossa imagem do Docker.
Criar uma imagem personalizada do Docker para o aplicativo Spring Boot
A criação de uma imagem personalizada exigirá que tenhamos um Dockerfile no lugar. Na base de seu projeto Java, adicione um arquivo Dockerfile e inclua o seguinte:
1 2 3 4 5 |
DE openjdk:8 COPY ./build/libs/java-project-0.0.1-SNAPSHOT.jar spring-boot.jar CMD java -jar spring-boot.jar |
No exemplo acima, estamos usando a imagem oficial do OpenJDK como base e estamos copiando nosso JAR para a imagem no momento da compilação. Na implantação, o JAR é executado.
Para criar essa imagem, execute o seguinte:
1 |
docker build -t spring-boot-custom /path/to/directory/with/dockerfile |
O comando acima deve parecer familiar. Estamos criando um bota de mola personalizada
usando o blueprint encontrado no diretório do nosso Dockerfile arquivo.
Para obter mais informações sobre a criação de imagens personalizadas do Docker, consulte um artigo anterior que escrevi chamado, Crie uma imagem personalizada do Docker para seu aplicativo da Web em contêiner.
Implantação das imagens do Couchbase e do Spring Boot como contêineres
Há algumas opções quando se trata de implementar nossas imagens. Podemos usar um arquivo Compose ou implementá-las como contêineres vanilla. Acho que o Compose é uma abordagem mais limpa, portanto, vamos usá-lo.
Em algum lugar de seu computador, crie um arquivo docker-compose.yml e inclua o seguinte:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
versão: '2' serviços: couchbase: imagem: couchbase-custom portos: - 8091:8091 - 8092:8092 - 8093:8093 ambiente: - COUCHBASE_ADMINISTRATOR_USERNAME=Administrador - COUCHBASE_ADMINISTRATOR_PASSWORD=senha - COUCHBASE_BUCKET=padrão - COUCHBASE_BUCKET_PASSWORD= bota de mola: imagem: spring-boot-custom portos: - 8080:8080 ambiente: - COUCHBASE_HOST=couchbase - COUCHBASE_BUCKET=padrão - COUCHBASE_BUCKET_PASSWORD= reiniciar: sempre |
No arquivo acima, estamos definindo as imagens personalizadas que criamos e estamos fazendo o mapeamento de portas para a máquina host. O que é particularmente interessante é a seção ambiente
opções. Elas correspondem às variáveis que temos em nosso application.properties e configure.sh arquivos.
Para implementar nossos contêineres com o Compose, execute o seguinte:
1 2 |
docker-compose run -d --service-ports --name couchbase couchbase docker-compose run -d --service-ports --name spring-boot spring-boot |
Algo a ser observado sobre os comandos acima. O Couchbase não é implantado instantaneamente. Você precisará esperar até que ele seja completamente iniciado antes de implantar o aplicativo Java. Depois que os dois aplicativos forem iniciados, verifique-os navegando até o aplicativo Java em seu navegador da Web.
Conclusão
Você acabou de ver como criar Docker para um aplicativo Spring Boot e um servidor Couchbase. Após a implantação de cada um como contêineres, eles poderão se comunicar entre si, o que é extremamente conveniente para a manutenção.
Se você estiver interessado em ver isso feito com o Node.js, confira o Artigo anterior Escrevi sobre o assunto. Se você estiver interessado em saber mais sobre o Java SDK para o Couchbase, consulte o Portal do desenvolvedor do Couchbase.
[...] se estiver interessado, você pode dar uma olhada em Use Docker to Deploy a Containerized Java with Couchbase Web Application e Deploy a Node.js with Couchbase Web Application as Docker Containers, dependendo do seu [...]