Aplicativos modernos no OpenShift, parte 2: compilações encadeadas
Olá a todos! Este é o segundo post de nossa série em que mostramos como implantar aplicações web modernas no Red Hat OpenShift.
Na postagem anterior, abordamos levemente os recursos da nova imagem do construtor S2I (source-to-image), que foi projetada para construir e implantar aplicativos da web modernos na plataforma OpenShift. Então estávamos interessados no tópico de implantação rápida de um aplicativo e hoje veremos como usar uma imagem S2I como uma imagem de construtor “pura” e combiná-la com assemblies OpenShift relacionados.
Limpar imagem do construtor
Como mencionamos na Parte XNUMX, a maioria dos aplicativos web modernos possui um chamado estágio de construção, que normalmente executa operações como transpilação de código, concatenação de vários arquivos e minificação. Os arquivos obtidos como resultado dessas operações - e estes são HTML, JavaScript e CSS estáticos - são armazenados na pasta de saída. A localização desta pasta geralmente depende de quais ferramentas de construção estão sendo usadas, e para React esta será a pasta ./build (voltaremos a isso com mais detalhes abaixo).
Fonte para imagem (S2I)
Neste post não abordamos o tema “o que é S2I e como usá-lo” (você pode ler mais sobre isso aqui), mas é importante ter clareza sobre as duas etapas desse processo para entender o que uma imagem do Web App Builder faz.
Fase de montagem
A fase de montagem é de natureza muito semelhante ao que acontece quando você executa docker build e obtém uma nova imagem do Docker. Conseqüentemente, esta etapa ocorre ao iniciar uma construção na plataforma OpenShift.
No caso de uma imagem do Web App Builder, ele é responsável por instalar as dependências do seu aplicativo e executar o build. montar roteiro. Por padrão, a imagem do construtor usa a construção npm run build, mas isso pode ser substituído por meio da variável de ambiente NPM_BUILD.
Como dissemos anteriormente, a localização do aplicativo finalizado e já construído depende das ferramentas que você usa. Por exemplo, no caso do React esta será a pasta ./build, e para aplicações Angular será a pasta project_name/dist. E, como já mostrado no post anterior, a localização do diretório de saída, que está configurado para build por padrão, pode ser substituída através da variável de ambiente OUTPUT_DIR. Bem, como a localização da pasta de saída difere de framework para framework, basta copiar a saída gerada para a pasta padrão na imagem, ou seja, /opt/apt-root/output. Isso é importante para a compreensão do restante deste artigo, mas por enquanto vamos examinar rapidamente o próximo estágio – a fase de execução.
fase de execução
Este estágio ocorre quando uma chamada para docker run é feita na nova imagem criada durante o estágio de montagem. O mesmo acontece ao implantar na plataforma OpenShift. Padrão executar script usa módulo de atendimento para servir conteúdo estático localizado no diretório de saída padrão acima.
Esse método é bom para implantar aplicativos rapidamente, mas geralmente não é recomendado servir conteúdo estático dessa forma. Bem, como na realidade servimos apenas conteúdo estático, não precisamos do Node.js instalado dentro da nossa imagem - um servidor web será suficiente.
Ou seja, na hora de montar precisamos de uma coisa, na hora de executar precisamos de outra. Nessa situação, as compilações encadeadas são úteis.
“Dois assemblies podem ser vinculados, um gerando uma entidade compilada e o outro hospedando essa entidade em uma imagem separada que é usada para executar essa entidade.”
Em outras palavras, podemos usar a imagem do Web App Builder para executar nossa construção e, em seguida, usar a imagem do servidor web, o mesmo NGINX, para servir nosso conteúdo.
Assim, podemos usar a imagem do Web App Builder como um construtor “puro” e ao mesmo tempo ter uma pequena imagem de tempo de execução.
Agora vamos ver isso com um exemplo específico.
Para treinamento usaremos aplicativo React simples, criado usando a ferramenta de linha de comando create-react-app.
Vejamos esse arquivo com mais detalhes e comecemos com a seção de parâmetros.
parameters:
- name: SOURCE_REPOSITORY_URL
description: The source URL for the application
displayName: Source URL
required: true
- name: SOURCE_REPOSITORY_REF
description: The branch name for the application
displayName: Source Branch
value: master
required: true
- name: SOURCE_REPOSITORY_DIR
description: The location within the source repo of the application
displayName: Source Directory
value: .
required: true
- name: OUTPUT_DIR
description: The location of the compiled static files from your web apps builder
displayName: Output Directory
value: build
required: false
Tudo aqui é bem claro, mas vale a pena prestar atenção no parâmetro OUTPUT_DIR. Para o aplicativo React em nosso exemplo, não há com o que se preocupar, pois o React usa o valor padrão como pasta de saída, mas no caso do Angular ou qualquer outro, esse parâmetro precisará ser alterado conforme necessário.
Dê uma olhada na terceira e quarta imagens. Ambos são definidos como imagens Docker e você pode ver claramente de onde vêm.
A terceira imagem é web-app-builder e vem de nodeshift/ubi8-s2i-web-app marcado como 10.x em Hub do Docker.
A quarta é uma imagem NGINX (versão 1.12) com a tag mais recente em Hub do Docker.
Agora vamos dar uma olhada nas duas primeiras imagens. Ambos estão vazios no início e são criados apenas durante a fase de construção. A primeira imagem, react-web-app-builder, será o resultado de uma etapa de montagem que combinará a imagem web-app-builder-runtime e nosso código-fonte. É por isso que adicionamos “-builder” ao nome desta imagem.
A segunda imagem - react-web-app-runtime - será o resultado da combinação de nginx-image-runtime e alguns arquivos da imagem react-web-app-builder. Esta imagem também será usada durante a implantação e conterá apenas o servidor web e HTML estático, JavaScript, CSS da nossa aplicação.
Confuso? Agora vamos dar uma olhada nas configurações de compilação e isso ficará um pouco mais claro.
Nosso modelo possui duas configurações de construção. Aqui está o primeiro, e é bastante padrão:
Como você pode ver, a linha com o rótulo 1 diz que o resultado desta construção será colocado na mesma imagem react-web-app-builder que vimos um pouco antes na seção ImageStreams.
A linha rotulada como 2 informa de onde obter o código. No nosso caso, este é um repositório git, e a localização, ref e pasta de contexto são determinadas pelos parâmetros que já vimos acima.
A linha rotulada como 3 é o que já vimos na seção de parâmetros. Ele adiciona a variável de ambiente OUTPUT_DIR, que em nosso exemplo é build.
A linha rotulada como 4 diz para usar a imagem web-app-builder-runtime, que já vimos na seção ImageStream.
A linha rotulada 5 diz que queremos usar uma construção incremental se a imagem S2I suportar, e a imagem do Web App Builder suporta. Na primeira inicialização, após a conclusão da etapa de montagem, a imagem salvará a pasta node_modules em um arquivo compactado. Então, nas execuções subsequentes, a imagem simplesmente descompactará esta pasta para reduzir o tempo de construção.
E, finalmente, a linha rotulada como 6 são apenas alguns gatilhos para fazer a compilação ser executada automaticamente, sem intervenção manual, quando algo muda.
No geral, esta é uma configuração de construção bastante padrão.
Agora vamos dar uma olhada na segunda configuração de compilação. É muito semelhante ao primeiro, mas há uma diferença importante.
Portanto, a segunda configuração de compilação é react-web-app-runtime e começa bem padrão.
A linha rotulada como 1 não é novidade - ela simplesmente diz que o resultado da compilação é colocado na imagem react-web-app-runtime.
A linha rotulada como 2, como na configuração anterior, indica de onde obter o código-fonte. Mas observe que aqui estamos dizendo que é tirado da imagem. Além disso, a partir da imagem que acabamos de criar - do react-web-app-builder (indicado na linha 3). Os arquivos que queremos usar estão dentro da imagem e sua localização está definida na linha 4, no nosso caso é /opt/app-root/output/. Se você se lembra, é aqui que são armazenados os arquivos gerados com base nos resultados da construção de nosso aplicativo.
A pasta de destino especificada no termo com rótulo 5 é simplesmente o diretório atual (lembre-se, isso é tudo executado dentro de alguma coisa mágica chamada OpenShift, e não no seu computador local).
A seção de estratégia – linha rotulada 6 – também é semelhante à primeira configuração de construção. Só que desta vez usaremos o nginx-image-runtime, que já vimos na seção ImageStream.
Finalmente, a linha rotulada como 7 é uma seção de gatilhos que ativarão esta compilação toda vez que a imagem do react-web-app-builder for alterada.
Caso contrário, este modelo contém configurações de implantação bastante padrão, bem como itens relacionados a serviços e rotas, mas não entraremos em muitos detalhes. Observe que a imagem que será implantada é a imagem react-web-app-runtime.
Implantação de aplicativos
Agora que vimos o modelo, vamos ver como usá-lo para implantar um aplicativo.
Podemos usar a ferramenta cliente OpenShift chamada oc para implantar nosso modelo:
O padrão aqui é o mesmo, exceto pela variável OUTPUT_DIR.
Complemento 2
Neste artigo utilizamos o NGINX como servidor web, mas é bastante fácil substituí-lo pelo Apache, basta alterar o template no arquivo imagem NGINX em Imagem Apache.
Conclusão
Na primeira parte desta série, mostramos como implementar rapidamente aplicações web modernas na plataforma OpenShift. Hoje vimos o que uma imagem de aplicativo da Web faz e como ela pode ser combinada com um servidor da Web puro como o NGINX usando construções encadeadas para criar uma construção de aplicativo mais pronta para produção. No próximo e último artigo desta série, mostraremos como executar um servidor de desenvolvimento para sua aplicação no OpenShift e garantir a sincronização de arquivos locais e remotos.
Parte 2: Como usar uma nova imagem S2I com uma imagem de servidor HTTP existente, como NGINX, usando assemblies OpenShift associados para implantação de produção;
Parte 3: como executar um servidor de desenvolvimento para sua aplicação na plataforma OpenShift e sincronizá-lo com o sistema de arquivos local.