Olá a todos. Continuamos a série de artigos sobre como escrever seu projeto.
Classifique os galhos
Da importância, para não me perder nas ramificações e sua ordem no repositório, resolvi renomeá-las adicionando o prefixo STEP_{number} . Por exemplo, temos três filiais além da principal:- JRTB-0
- JRTB-2
- JRTB-3
- STEP_1_JRTB-0 - primeira etapa
- STEP_2_JRTB-2 - segunda etapa
- STEP_3_JRTB-3 - terceira etapa
Um pouco sobre Docker
O que é Docker? Resumindo, é uma ferramenta com a qual você pode implantar (implantar) aplicações de forma rápida e segura, criando para elas uma infraestrutura fechada que só é necessária para elas. Ainda é difícil, eu entendo. Em geral, Docker pode ser entendido como uma plataforma de desenvolvimento onde você pode trabalhar de forma rápida e eficiente. Docker pode ser entendido como um programa executado em um servidor. Este programa tem a capacidade de armazenar contêineres com aplicativos. O que é um contêiner? Esta é uma infraestrutura separada na qual você pode adicionar tudo o que precisa. Por exemplo, para uma aplicação Java precisamos de um JRE para executar a aplicação, o contêiner terá isso, precisaremos de algum outro software - podemos adicionar isso. Ou talvez precisemos de Linux e de um contêiner de servlet Tomcat. Isso também pode ser feito. Os contêineres são criados com base em uma imagem: ou seja, este é um modelo específico que contém tudo o que é necessário para criar um contêiner Docker. Como criar esta imagem? No nosso caso, precisaremos criar um Dockerfile na raiz do projeto descrevendo o que deve estar no container. Como não queremos expor o token do bot em lugar nenhum, teremos que repassá-lo sempre que quisermos implantar o aplicativo. Você pode ler mais sobre este assunto aqui e aqui .Escrevemos JRTB-13
Precisamos configurar um processo de implantação rápido e fácil de nosso aplicativo no servidor. Ou seja, para uma máquina que funciona 24 horas por dia, 7 dias por semana. Vamos tomar o Docker como base. Mas não há nenhuma tarefa em nossa lista que seja responsável por adicionar essa funcionalidade. De alguma forma, eu perdi isso ao criá-lo. Não tem problema, vamos criá-lo agora. Vá para a aba de criação de problemas no GitHub e selecione Solicitação de recurso: Adicione uma descrição da tarefa, critérios para sua aceitação, defina a qual projeto este problema pertence e você pode criar um novo problema: Agora, para mostrar que a tarefa foi aceita para o trabalho, altere o status da tarefa de A fazer para Em andamento: este será um artigo difícil. Se você tiver algum problema, escreva nos comentários: irei monitorar e responder da melhor maneira possível. Este será um pequeno Apoio ao Cliente :DCriando um Dockerfile
O que é um arquivo docker? Para Docker, este é um script (instruções passo a passo) sobre como criar uma imagem para um contêiner Docker. Para que nosso aplicativo funcione, precisamos do JDK, versão 11. Ou seja, precisamos encontrar a imagem docker JDK 11 e adicioná-la à nossa imagem. Isso é algo semelhante a como adicionamos uma dependência a uma memória. Docker possui DockerHub para essa finalidade . Para baixar imagens localmente, você precisa se registrar lá. Após o registro, vamos procurar o JDK11. Pelo que descobri, este é o contêiner: adoptopenjdk/openjdk11 . A descrição deste contêiner contém o que é necessário para o dockerfile:FROM adoptopenjdk/openjdk11:ubi
RUN mkdir /opt/app
COPY japp.jar /opt/app
CMD ["java", "-jar", "/opt/app/japp.jar"]
Vamos consertar a pasta da qual retiramos o arquivo jar. Nós o colocamos na pasta de destino depois de executarmos a tarefa maven do pacote mvn. Antes de fazer tudo isso, com base no branch principal atualizado, criamos um novo para nossa tarefa: STEP_4_JRTB-13 . Agora você pode trabalhar. Na raiz do projeto, crie um arquivo sem a extensão Dockerfile e adicione o seguinte dentro:
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
A primeira linha é onde a imagem será baseada - adoptopenjdk/openjdk11. A segunda linha serve para adicionar um argumento à imagem chamada JAR_FILE, que está localizada na pasta de destino. Além disso, a pasta atual é determinada pela localização do Dockerfile. Terceira linha - copie o jar do nosso projeto para a imagem do docker. A última linha contém essencialmente um array criado a partir do comando no terminal, que foi separado por espaço. Ou seja, no final será executado o seguinte: “java -jar /app.jar” Para manter o token do bot em segredo, ao iniciar o container precisaremos passar duas variáveis – o nome do bot e seu token. Para fazer isso, escreveremos uma consulta que deverá lançar nosso projeto com variáveis. E como fazer isso? Você precisa pesquisar no Google: aqui está o primeiro link com uma descrição normal. O que nós queremos fazer? Temos duas variáveis no arquivo application.properties que definimos lá:
- bot.nome de usuário
- bot.token
- Vamos executar o script bash.
- O script bash executa o docker-compose.
- Docker-compose lança um contêiner docker com nosso aplicativo.
- O contêiner Docker executa nosso aplicativo.
FROM adoptopenjdk/openjdk11:ubi
ARG JAR_FILE=target/*.jar
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java", "-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}", "-jar", "/app.jar"]
Você pode ver que adicionamos duas linhas e atualizamos o ENTRYPOINT. Linhas:
ENV BOT_NAME=test.javarush_community_bot
ENV BOT_TOKEN=1375780501:AAE4A6Rz0BSnIGzeu896OjQnjzsMEG6_uso
declare variáveis dentro do arquivo do codificador. Por padrão, eles têm um valor especificado. Se, ao criar uma imagem a partir deste dockerfile, forem passadas variáveis de ambiente com tais nomes, os valores serão diferentes. E no ENTRYPOINT adicionamos mais alguns elementos que irão ler estas variáveis de ambiente:
"-Dbot.username=${BOT_NAME}", "-Dbot.token=${BOT_TOKEN}"
Aqui você pode ver que dentro da linha, usando a construção ${}, os valores de BOT_NAME e BOT_TOKEN serão passados. A seguir, precisamos ensinar como receber e passar essas variáveis para o docker-compose.
Crie docker-compose.yml
Seria bom que você lesse sobre o formato YAML separadamente, caso contrário o artigo já está crescendo aos trancos e barrancos. Para nós, esta é apenas mais uma descrição de variáveis do tipo .properties. Somente nas propriedades é escrito através de um ponto, mas no YAML isso é feito de maneira um pouco mais bonita. Por exemplo, assim. Duas variáveis em .properties: javarush.telegram.bot.name=ivan javarush.telegram.bot.token=pupkin Mas em .yaml (o mesmo que .yml) será assim:javarush:
telegram:
bot:
name: ivan
token: pupkin
A segunda opção é mais bonita e compreensível. Os espaços devem ser exatamente como indicados acima. Vamos traduzir nosso application.properties e application.yml de alguma forma. Primeiro você precisa criá-lo. Na raiz do projeto, crie um arquivo docker-compose.yml e escreva o seguinte:
version: '3.1'
services:
jrtb:
build:
context: .
environment:
- BOT_NAME=${BOT_NAME}
- BOT_TOKEN=${BOT_TOKEN}
restart: always
A primeira linha é a versão docker-compose. services: diz que todas as linhas seguintes (serão deslocadas) referem-se aos serviços que estamos configurando. Temos apenas um deles até agora - um aplicativo Java chamado jrtb . E já abaixo dele estarão todas as suas configurações. Por exemplo, construir: contexto: . diz que procuraremos o Dockerfile no mesmo diretório que docker-compose.yml. Mas a seção Environment: será responsável por garantir que passaremos as variáveis de ambiente necessárias para o Dockerfile. Exatamente o que precisamos. Portanto, passamos variáveis abaixo. O Docker-compose irá procurá-los nas variáveis do ambiente operacional do servidor. Vamos adicioná-los ao script bash.
Criando scripts bash
A última etapa é criar um script bash. Crie um arquivo chamado start.sh na raiz do projeto e escreva o seguinte lá:#!/bin/bash
# Pull new changes
git pull
# Prepare Jar
mvn clean
mvn package
# Ensure, that docker-compose stopped
docker-compose stop
# Add environment variables
export BOT_NAME=$1
export BOT_TOKEN=$2
# Start new deployment
docker-compose up --build -d
A primeira linha é necessária para todos os scripts bash: não funcionará sem ela. E então - apenas um conjunto de comandos no terminal que precisam ser executados. Adicionei comentários em cada comando para que fique claro. A única coisa que quero explicar é o que significam $1 e $2. Estas são duas variáveis que serão passadas quando o script bash for iniciado. Usando o comando export, eles serão adicionados às variáveis do servidor e lidos no docker-compose. Isso funciona para o Ubuntu, provavelmente não para o Windows, mas não tenho certeza. Agora você precisa adicionar o script stop.sh, que interromperá o trabalho. Ele conterá várias linhas:
#!/bin/bash
# Ensure, that docker-compose stopped
docker-compose stop
# Ensure, that the old application won't be deployed again.
mvn clean
Aqui paramos o docker-compose e limpamos o jarnik do projeto, que está disponível desde a última compilação. Fazemos isso para garantir que nosso projeto seja reconstruído com precisão. Houve precedentes, por isso estou acrescentando) Como resultado, acabamos com 4 novos arquivos:
- Dockerfile - um arquivo para criar uma imagem da nossa aplicação;
- docker-compose.yml - um arquivo com configurações de como iniciaremos nossos contêineres;
- start.sh - script bash para implantar nosso aplicativo;
- stop.sh é um script bash para interromper nosso aplicativo.
# Notas de versão ## 0.3.0-SNAPSHOT * JRTB-13: processo de implantação adicionado ao projeto ## 0.2.0-SNAPSHOT * JRTB-3: padrão de comando implementado para lidar com comandos do Telegram Bot ## 0.1.0-SNAPSHOT * JRTB -2: adicionado bot de telegrama stub * JRTB-0: adicionado projeto de esqueleto SpringBoot
E no README adicionaremos um novo parágrafo descrevendo como implantar nossa aplicação:
## Implantação Processo de implantação o mais fácil possível: Software necessário: - terminal para executar scripts bash - docker - docker-compose para implantar o aplicativo, mudar para o branch necessário e executar o script bash: $ bash start.sh ${bot_username} ${bot_token } Isso é tudo.
Claro, tudo está escrito em inglês. Como de costume, em nosso branch recém-criado STEP_4_JRTB-13 criamos um novo commit com o nome: JRTB-13: implemente o processo de implantação via docker e faça push dele. Deixo de me alongar em coisas que já descrevi em artigos anteriores. Não vejo sentido em repetir a mesma coisa. Além disso, quem descobriu e fez sozinho não terá dúvidas. Sou eu falando sobre como criar um novo branch, como criar um commit, como enviar um commit para o repositório.
GO TO FULL VERSION