Mostrando postagens com marcador Docker. Mostrar todas as postagens
Mostrando postagens com marcador Docker. Mostrar todas as postagens

quinta-feira, 27 de agosto de 2020

Como você escreve um Dockerfile?

Photo by Jonas Smith on Unsplash

Um Dockerfile é um documento de texto (sem uma extensão de arquivo) que contém as instruções para configurar um ambiente para um contêiner do Docker. Você pode construir uma imagem Docker usando um Dockerfile.
O comando docker build . constrói uma imagem Docker usando o Dockerfile no diretório em que este comando é executado.
Aqui está um exemplo de arquivo docker:

# Usando a imagem oficial do Ubuntu como uma imagem pai
FROM ubuntu:latest

# Configurando o diretório de trabalho para /app
WORKDIR /app

# Copie o conteúdo do diretório atual para o contêiner em /app
COPY . /app

# Obtendo as atualizações para o Ubuntu e instalando o Python em nosso ambiente
RUN apt-get -y update  && apt-get install -y python

# Execute app.py quando o contêiner for iniciado
CMD ["python", "app.py"]

O Dockerfile é explicado linha por linha abaixo:

# Usando a imagem oficial do Ubuntu como uma imagem pai
FROM ubuntu:latest

A maioria dos arquivos docker começa a partir de uma imagem "pai". A imagem pai é adicionada por meio da palavra-chave FROM. Sua imagem se baseia na imagem principal. Adicionamos a imagem oficial do Ubuntu usando FROM ubuntu:latest.

# Configurando o diretório de trabalho para /app
WORKDIR /app

Em seguida, você define o diretório de trabalho em seu contêiner com WORKDIR. WORKDIR /app define o diretório atual para /app quando o contêiner começa a ser executado.

# Copie o conteúdo do diretório atual para o contêiner em /app
COPY . /app

Até agora, temos o Ubuntu OS em nosso ambiente com o diretório atual definido como /app. Agora, queremos transferir nossos próprios arquivos de fora para o contêiner. Fazemos isso usando COPY . /app em que o comando COPY copia todos os arquivos de nosso diretório atual (aquele que contém o Dockerfile) para o /app. Nosso contêiner conterá agora o Ubuntu OS e os arquivos de nosso diretório local com o diretório de trabalho definido como ./app. É isso aí! O contêiner terá apenas as coisas que você especificar.

# Obtendo as atualizações para o Ubuntu e instalando o Python em nosso ambiente
RUN apt-get -y update  && apt-get install -y python

O comando RUN é executado quando construímos a imagem e quaisquer dependências ou pacotes adicionais são geralmente instalados usando o comando RUN. Assumimos que temos a imagem do sistema operacional que especificamos e construímos outros pacotes sobre ela.

# Execute app.py quando o contêiner for iniciado
CMD ["python", "app.py"]

O CMD especifica o comando que é executado quando iniciamos o contêiner.
Nota: Você pode inserir comentários em seu Dockerfile usando #.

Fonte: How do you write a Dockerfile?
Licença: Creative Commons -Attribution -ShareAlike 4.0 (CC-BY-SA 4.0)

segunda-feira, 24 de agosto de 2020

Introdução ao Docker2 - compor e empacotar um aplicativo Spring Boot no Docker

Imagem de Pexels por Pixabay

Introdução

No artigo anterior, vimos o que é o Docker, como os contêineres são úteis como uma nova tendência de devOps e aprendemos a diferença entre contêineres e imagens. Também aprendemos sobre Dockerfile.
Agora, aprenderemos sobre o comando docker-compose e como executar um aplicativo SpringBoot de um contêiner local. Mas, antes de fazer isso, precisamos empacotar um aplicativo SpringBoot com o Docker. Vamos ver como fazer.

Dockerizing um aplicativo SpringBoot

A primeira coisa que faremos é obter um aplicativo básico baseado em SpringBoot que podemos encaixar. Para esse propósito, podemos usar o aplicativo básico que vem com o andaime Spring ao usar o Spring Initializr no IntelliJ, e podemos adicionar um endpoint muito simples que retornará uma mensagem de saudação no formato JSON.
Não importa se você não tem o Spring Initializr, desde que você possa expor um endpoint e consultá-lo por meio do objeto de teste mockMvc ou de uma ferramenta como o Postman. Para referência, aqui está nossa estrutura de pacote de aplicativo:

Você pode notar que o Dockerfile é colocado na pasta raiz de todo o projeto. Este será o arquivo usado para controlar todos os detalhes da nossa imagem, sua especificação.
Em seguida, o arquivo será usado para criar uma imagem Docker e, a partir dessa imagem, quando estiver efetivamente em execução, teremos nosso contêiner.
Para encaixar nosso aplicativo SpringBoot (ou qualquer aplicativo), é necessário especificar em nosso Dockerfile tudo o que precisamos para executar nosso aplicativo. Precisa ser, em essência, uma descrição em camadas de todas as etapas que tomaríamos para construir e executar nosso aplicativo, localmente, em um formato que pode ser:

  • reproduzível: um Dockerfile deve sempre resultar na mesma imagem depois de executado e totalmente especificado. Qualquer pessoa que usar essa imagem sempre obterá exatamente a mesma funcionalidade.
  • independente do ambiente: em essência, o poder do Docker depende do fato de que muitos serviços de infraestrutura e devOps agora o suportam em seus pipelines de desenvolvimento para que, sempre que um envio de novo código para um branch especificado acontecer, ele acione uma reconstrução completa de a imagem do Docker. Em seguida, os desenvolvedores podem usá-lo via docker-compose perfeitamente ou a imagem mais recente estará disponível em um registro para ser exposta como um micro-serviço para o mundo via nginx, etc.

Uma vez que a única coisa que realmente precisamos para iniciar o aplicativo SpringBoot após o término da compilação é o arquivo .jar contendo o código compilado, contanto que usemos uma imagem Java base para construir a nossa, podemos envolver nosso aplicativo SpringBoot em um Contêiner do Docker definindo o ponto de entrada como executando o arquivo .jar:

FROM openjdk:8
COPY target/greeter-*.jar greeter.jar
EXPOSE 8080
ENTRYPOINT ["java","-jar","greeter.jar"]

Portanto, construímos nossa imagem a partir de uma imagem base Java 8 openJDK e, em seguida, copiamos o arquivo JAR (que precisa existir em nossa máquina local no mesmo nível de pasta de destino e o próprio Dockerfile) de nosso sistema local para o diretório raiz do contêiner.
Em seguida, expomos a porta 8080 do contêiner para ficar disponível para o exterior. Esta é a mesma porta do serviço SpringBoot; caso contrário, o contêiner não saberá onde o serviço está sendo executado.
Por fim, chamamos o Java para iniciar nosso serviço a partir do JAR que acabamos de copiar para o contêiner de nossa máquina local. Isso significa que, ao iniciar um contêiner a partir da imagem construída por meio deste Dockerfile, iniciaremos efetivamente o aplicativo SpringBoot.

O comando docker-compose

O Dockerfile nos permite especificar o que é necessário para construir uma imagem.
docker-compose é um comando que nos permite especificar e iniciar vários serviços compostos de muitas imagens Docker juntos, de forma coordenada, enquanto nos permite especificar qual imagem usar para qual serviço e garantir que os serviços sejam iniciados corretamente. Também nos permite definir as variáveis de ambiente que são expostas como tal no contêiner em execução.
Vamos supor que nosso aplicativo exige autenticação de nome de usuário e senha em nosso endpoint. Para definir essas variáveis, podemos escrever um arquivo docker-compose.yml que colocamos no mesmo nível que o Dockerfile, e lá, podemos especificar de qual Dockerfile construir o contêiner, qual imagem usar (ambos para local cria e usa imagens remotas), que atende a composição de contêineres que usará e as variáveis de ambiente necessárias.
Um simples docker-compose.yml poderia ser:

version: '3'
services:
  web:
    build: .
    ports:
      - "8080:8080"
  environment:
    - username="User"
    - password="Pass"

Definimos um serviço chamado web que é construído a partir do Dockerfile no diretório atual, expõe a porta 8080 para o exterior e o serviço em execução no contêiner também está na porta 8080.
Em seguida, definimos as variáveis de ambiente disponíveis para nosso serviço, assim como definimos em um arquivo application.properties ou em um shell.
Para usar este arquivo para iniciar um contêiner, simplesmente fazemos:
docker-compose -f <caminho para compor o arquivo> -d up
Isso usará o arquivo de composição para construir e instanciar nosso contêiner e iniciar o serviço configurado com esse ambiente.
-d garante que o contêiner continue em execução em segundo plano e o inicializa.
O Compose permite aos desenvolvedores extrair uma imagem localmente em suas máquinas, executá-la e testá-la localmente, o que é muito útil.

Conclusão

Vimos o que é docker-compose, como ajuda os desenvolvedores a testar certas funcionalidades e como isola questões em um ambiente controlado. Também vimos o que é necessário para empacotar um aplicativo SpringBoot com Docker.

Fonte: Intro to Docker 2- Docker-compose and packaging a SpringBoot application by Bruno Oliveira
Licença: Creative Commons -Attribution -ShareAlike 4.0 (CC-BY-SA 4.0)

Introdução ao Docker - contêineres, imagens e o Dockerfile

Imagem de Valdas Miskinis por Pixabay

Introdução

Docker é um sistema de conteinerização que permite aos desenvolvedores e equipes lidar com a implantação e dimensionamento de aplicativos de uma maneira muito mais fácil.
Assim como o nome sugere, podemos pensar em um contêiner como um sistema isolado que contém tudo o que é necessário para executar um determinado aplicativo em uma determinada configuração.
As imagens podem ser pré-construídas, recuperadas de registros, criadas a partir de registros já existentes, combinadas, iniciadas por meio de uma rede comum, etc.
Veremos a diferença entre uma imagem e um contêiner, como eles se relacionam e como esses dois conceitos nos permitem tornar um aplicativo independente e pronto para ser implantado.

Imagens e recipientes

Podemos pensar em imagens e contêineres como dois estados diferentes do mesmo conceito subjacente. Basicamente, podemos dizer que um container é uma instância em execução de uma imagem que empacota e representa um determinado aplicativo. Para fins de analogia, vamos voltar às classes e objetos Java. Um contêiner pode ser visto como um objeto e uma imagem pode ser vista como a classe.
As imagens são usadas para iniciar os contêineres. A partir de contêineres em execução, podemos obter imagens, e tudo isso pode ser composto em conjunto para formar uma maneira muito poderosa e independente do sistema de empacotar e implantar aplicativos. Gosto de pensar nisso quase como "enviar seu host local". Por quê? Como o Docker requer que todas as configurações necessárias para executar um aplicativo estejam contidas e instaladas em uma imagem, criar uma imagem é essencialmente replicar o estado de execução atual do ambiente e do aplicativo, agrupando-o e disponibilizando-o na nuvem.

Então, para recapitular:

  • As imagens podem ser recuperadas de registros que contêm várias imagens pré-construídas para serem usadas pelos desenvolvedores para construir imagens mais complexas.
  • Os contêineres podem ser vistos como instâncias em execução de imagens. É possível orquestrar vários contêineres para serem iniciados e interrompidos como um "serviço agrupado", o que permite efetivamente que aplicativos inteiros sejam estruturados como um cluster de contêineres Docker relacionados.

Dockerfile - A maneira de encaixar um aplicativo

Para encaixar um aplicativo, o fluxo que seguimos é criar uma imagem Docker que é construída sobre uma já existente e contém, por exemplo, nosso aplicativo JAR ou o script de inicialização de um aplicativo Python como seu comando de inicialização.
Um comando de inicialização para um contêiner é o comando que será executado quando o contêiner for iniciado. Portanto, essencialmente, a instância em execução de nossa imagem se torna o contêiner que executa nosso aplicativo.
Um Dockerfile é uma especificação que usamos para construir um novo contêiner a partir de uma imagem pré-construída e adicionar nossa lógica customizada para iniciar nosso aplicativo. Em um Dockerfile, usamos o comando docker build para construir uma imagem.
Um Dockerfile funciona em camadas. A primeira camada começa com a palavra-chave FROM e define qual imagem pré-construída usar para construir nossa própria imagem. Posteriormente, podemos definir mais coisas como permissões de usuário, quais arquivos copiar para o contêiner do sistema local (pense, por exemplo, o requirements.txt de um aplicativo da web Python) e quais scripts de inicialização executar. Abaixo está um exemplo de Dockerfile:

FROM python:3
 
WORKDIR /usr/src/app
 
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt
 
COPY . .
 
CMD [ "python", "./your-daemon-or-script.py" ]

Vamos revisar o conteúdo deste Dockerfile simples e ver o que está acontecendo.
A primeira linha, FROM python: 3, está declarando que a imagem que vamos construir se expandirá na imagem base que contém todo o tempo de execução necessário para executar aplicativos baseados em Python 3.
Todos os comandos após este serão aplicados sobre a imagem Python 3 já existente e, como resultado, criaremos nossa própria imagem personalizada Python 3 que contém nosso aplicativo.
WORKDIR define o diretório de trabalho. O diretório especificado será assumido para qualquer outro comando que segue no Dockerfile e onde nosso aplicativo está. Nos comandos CMD e COPY abaixo, o diretório . refere-se ao WORKDIR.
Posteriormente, o comando COPY é usado para copiar arquivos de nosso sistema de arquivos local, onde está o Dockerfile, para o contêiner para que esses arquivos estejam prontamente disponíveis em nossa imagem.
O comando RUN é autodescritivo e executa um determinado comando, que, neste exemplo, está instalando nossas dependências.
Finalmente, o comando CMD define o comando de inicialização a ser executado quando o contêiner é iniciado; neste caso, simplesmente iniciaremos nosso aplicativo.

Conclusão

Esses conceitos básicos são a base sobre a qual o Docker desenvolve recursos adicionais. Depois de conhecer esses conceitos, você pode aprender qualquer outra coisa. Agora você pode construir suas próprias imagens e entender o que verá quando encontrar um Dockerfile em um projeto do Docker.
Por último, mas não menos importante, você pode encontrar muitas imagens oficiais pré-construídas no Docker Hub.
A seguir, veremos como empacotar um aplicativo Springboot simples com o Docker e apresentaremos o comando docker-compose e o arquivo docker-compose.

Fonte: Intro to Docker - Containers, images, and the Dockerfile
Licença: Creative Commons -Attribution -ShareAlike 4.0 (CC-BY-SA 4.0)