Transcrições
1. Introdução ao curso: Olá, é o máximo e
bem-vindo ao meu curso sobre como escurecer seus aplicativos
Python. Agora, como qualquer
desenvolvedor de software sabe, Darker desempenha um papel muito
importante em sua carreira de
desenvolvimento de software pois permite que você se sinta
confiante de que tudo o que você tem localmente é na verdade
a mesma coisa. E também
funcionará da mesma forma em uma máquina diferente,
também na nuvem e em
um ambiente de produção. Além disso, também
fornecerá muitas ferramentas muito
boas para criar
facilmente
imagens diferentes, para que você tenha todos os tipos de software
facilmente disponíveis. Mas queremos ter certeza de que
usamos o escuro corretamente. Portanto, neste curso,
aprenderemos o básico de como escrever
seu primeiro arquivo Docker, como fazer uma compilação em vários estágios e também como usar o docker-compose
para que você possa seu aplicativo Python verdade, qualquer outro
código que exista. Mas, neste caso,
estamos nos concentrando apenas no Python e, na verdade, executá-lo usando o docker, criando a imagem do Docker e,
em seguida, executando o contêiner do Docker, tanto por meio dos comandos regulares do
Docker quanto bem como sobre o
Docker Compose. Agora, esse curso é
, na verdade, parte de uma série maior de Python. Aprenderemos como
criar um aplicativo
Python completo do zero. Mas nesse caso,
vamos nos
concentrar apenas na parte mais escura. Então, o código
que vamos usar é dessa série
maior de Python. E você realmente
poderá acessá-lo usando o link
do GitHub abaixo na descrição
do curso. No entanto,
obviamente, você também pode usar seu próprio código Python
para os mesmos propósitos. Ou você pode usar o
código que já está no GitHub se quiser. De qualquer forma, você também encontrará
cada uma dessas lições como diferentes branches do GitHub e esse repositório do GitHub abaixo. Então, se você quiser
acompanhar o código, certifique-se de verificar
isso também. Então, sem mais delongas, eu vou ver você lá dentro
e feliz aprendendo.
2. Docker Introdução: Tudo bem, então, nesta seção, vamos começar a aprender
sobre o Docker e
vamos integrar o Darker
em nosso aplicativo. Agora, o Dr. é um programa
muito legal e, na verdade, eu recomendo que você baixe o Docker no Google ou simplesmente acesse este URL aqui, docker.com slash products
slash Docker Desktop. E para mim, como
estou em um Mac, ele vai
me dar as opções do Mac. Mas se você estiver usando um
Windows ou Linux, padrão será esses
e apenas certifique-se de fazer o download
, pois são algumas centenas de megabytes. Portanto, o download pode levar alguns
minutos. Eu já
fiz isso. Então, sim. Para o Docker, o docker é muito bom
porque nos ajuda a resolver outro tipo de problema
que já começamos a resolver quando estávamos falando
sobre ambientes virtuais. Então, se você se lembra de voltar
aos ambientes virtuais, ou a principal motivação foi
que queremos ter
certeza de que temos
tudo consistente. E, em certo sentido, um
pouco isolado para todos os
pacotes Python de que precisamos. Então, por exemplo, se nosso aplicativo
precisa de uma API rápida para ser executado, queremos ter certeza de que
todos que tentam executar nosso código tenham o FastAPI instalado, bem como
todas as outras coisas que eles também precisam para
executá-lo aplicativo. E isso não está
dizendo a eles como, Oh, ei, você está perdendo
essa instalação, você está perdendo
aquela instalação ou eles estão tentando usar
as instalações locais. E então há uma incompatibilidade de
versão, por exemplo, estamos usando alguma versão
como eu não sei, como dez pontos qualquer. E eles estão usando uma versão
como nove pontos, qualquer que seja. E há uma incompatibilidade de versões. Então, todas essas
coisas são coisas que tentamos resolver
usando ambientes virtuais. E é ótimo e tem
sido extremamente útil. Mas, na verdade, há mais coisas
que podemos fazer para tornar isso ainda
mais consistente. E a ideia aqui é
que, com mais escuro, podemos criar contêineres
isolados. Então, basicamente, pense nela como uma caixa que podemos
construir do zero, incluindo o sistema operacional. E sabemos que não importa
onde isso aconteça, se dermos as instruções
adequadas,
ele terá a mesma aparência em todos os lugares. E agora você pode estar
se perguntando, por que
quereríamos fazer isso soa
um pouco como um exagero. Bem, na verdade, existem certos cenários
e eu mesmo já encontrei isso várias
vezes em que você pode instalar algo em um Mac e ele
pode não funcionar corretamente, ou pode funcionar de
forma diferente em um Linux, ou coisas, estão funcionando em um
Linux de uma maneira, funcionam de
uma maneira diferente e, em seguida,
funcionam no Windows
como uma terceira maneira. Ou você também tem coisas locais já instaladas
que você pode ter esquecido porque as
instalou seis meses, um
ou dois anos atrás. E então outra pessoa
tenta executar seu código
e diz:
“Ei, essas coisas
não estão funcionando. E é só porque há algumas coisas que
você instalou que você esqueceu e que
elas não têm. Portanto, usar o Docker nos
ajuda a resolver
todos esses problemas. E, na verdade
, há muito mais
coisas legais que podemos fazer com isso e analisaremos
no futuro. Mas vamos
nos concentrar agora. Primeiramente, basta usar o Docker
para criar essencialmente uma caixa extremamente limpa que contém nosso aplicativo que, não importa onde você execute, ele será consistente. E, na verdade, o Docker é usado em todo o mundo. Quando
você está implantando código, normalmente você estará
implantando esse código como uma imagem do Docker que
será executada em algum lugar. Então, sim, mais sombrio, muito importante
para que isso realmente
nos ajude a obter tudo
consistente da base para cima, de ter o mesmo
sistema operacional que está rodando
nas mesmas versões da linguagem de
programação R, o mesmo e, em seguida, usando nossos ambientes virtuais para
instalar pacotes consistentes. Por isso, só queremos ter
certeza de que tudo é o mesmo, não importa onde você o execute e o escurecimento nos permitirá
fazer isso. E é extremamente,
extremamente útil porque então você nunca
precisa se preocupar? Ah, esqueci algo que também precisa ser
instalado, que eu
instalei ou existe
algum variável de ambiente que eu defini e que talvez eu
tenha esquecido? Ou, você sabe, todos
esses tipos de esquisitices estranhas que podem surgir. E depois, especialmente lidar
com problemas como, Uau, por que não
funciona na sua máquina? Está funcionando bem na minha máquina. Você instalou as coisas do
ambiente virtual corretamente? Sim, você fez.
OK. Isso é estranho. Por exemplo, por que está funcionando na
minha máquina e na sua? Darker vai nos ajudar a
aliviar todos esses problemas. E então, como veremos mais adiante, na verdade, existem mais algumas coisas
legais que podemos fazer que tornarão sua vida
muito mais fácil com o Docker, por exemplo, também como criar
um banco de dados que
possamos usar ou criando
um dinheiro que possamos usar. E muitas coisas legais por vir. Mas vamos nos concentrar em isolar nosso aplicativo
primeiro para que possamos simplesmente dar essa imagem a
alguém e, em seguida, essa pessoa possa executá-la e obter exatamente
a mesma coisa que estamos vendo do nosso lado. Então, sim, com isso, eu recomendaria apenas o Google, baixe o docker Desktop e seu mecanismo de busca favorito
ou acesse este site aqui, que pode mudar com o
tempo, provavelmente não, mas Os produtos de corte do docker.com
reduzem o Docker Desktop. E então vá
em frente e baixe a versão mais escura para você.
Novamente, eu já fiz isso. Então, para mim, quando eu
desempacoto a imagem, tudo o que preciso fazer é arrastá-la daqui
para meus aplicativos. Depois de fazer isso, vá em frente e acesse
seus aplicativos. E aqui agora você quer
clicar duas vezes no mais escuro e fazer com que ele funcione para mim, porque eu
já o executei antes. Só vai começar
a funcionar. E você
vê, na verdade, se você estiver em um Mac e no
canto superior direito, haverá uma pequena nave parecida com essa, que vai começar a
pular em um Windows. Vamos falar sobre
isso em um segundo. Mas sim, espere até que isso abra. É a primeira vez que
você vai usá-lo. Solicitará que você
leia e aceite os termos e condições antes do início da inscrição
. Então, sempre que esse
pop-up
aparecer, certifique-se
de fazer isso. E novamente em um Mac
no canto superior direito, geralmente na sua
barra de ferramentas lá em cima, que está atualmente
fora da minha tela, você deve ver uma baleia como essa com os
recipientes circulando, o que significa que estava começando. E uma vez que ele
assume uma forma fixa, isso significa que foi
iniciado corretamente. E depois de aceitar
os termos e condições e
a startup começar, você poderá
acessar seu PyCharm. Agora, se você digitar
mais escuro aqui, verá uma saída aqui que indicará que a instalação
foi bem-sucedida. Se você tiver algum
problema com isso, a primeira coisa que eu recomendaria
é, antes de tudo, esperar que seu Docker
termine de abrir. E se ainda estiver
com problemas, tente reiniciar o PC, você não precisa, mas geralmente é
bom tentar. E então, quando você
digita mais escuro aqui, você deve ver que ele responde
a algum tipo de saída. Nós temos aqui. Para o lado do Windows. Estaremos na mesma
página e podemos ver aqui já
estou recomendando
a versão para Windows. Vá em frente e clique em
Baixar aqui, que eu
já
fiz porque o download leva alguns
minutos. Em seguida, você
abrirá o instalador. Ele perguntará
se você quiser abrir isso, clique em Sim. E então
abriremos o instalador
ou
haverá duas caixas de seleção que serão marcadas por
padrão. Basta deixá-los e clicar em Avançar. Em seguida,
a instalação será iniciada, o que novamente leva
alguns minutos. Então, eu meio que vou deixá-lo
rodar em segundo plano. E esse é o estado em
que você chegará, onde dirá que a
instalação foi bem-sucedida. E então vamos clicar em
fechar e reiniciar. Então, vamos reiniciar
nossa máquina para isso. Então, depois de reiniciar no lado do
Windows, também
receberemos esse pop-up aqui. Vou aceitar os termos e
continuar com isso. E agora o Docker
abrirá caso você
receba esse pop-up. Vamos seguir mais
algumas instruções aqui para obter o processo de instalação. Então,
vamos rapidamente fazer isso. Tire isso do caminho. Siga as instruções aqui. Donald, isso aqui, bem rápido. Abra, execute e simplesmente
passe por esse processo. E então eu já tenho o
PyCharm aberto aqui. Eu vou pegar isso e
vou simplesmente copiá-lo. Acesse o PyCharm, que já
tem o PowerShell aberto. Cole isso aí. Só vou clicar em Reiniciar mais uma vez. E depois
de reiniciar aqui, se continuarmos com nosso Docker, agora
devemos ver que Docker Desktop está começando
a abrir esse aplicativo. Se formos para o canto inferior direito, também
lá, o que para
mim está atualmente fora da tela. Mas também há que você deve
ser capaz de ver se você clica nessa pequena
seta da janela que você sempre tem, que você tem essa coisa de navio
mais escura aqui. E então você tem
os contêineres que deveriam estar se movendo.
E também lá. Se você clicar nele, ele
deverá levá-lo volta ao aplicativo Docker,
como temos aqui. Ok, agora
entrando em nosso PyCharm, se clicarmos ou
digitarmos mais escuro aqui. E também do lado
do Windows, esse comando agora deve estar registrado com algo e
nos veremos em um segundo. Agora temos a saída
associada a ele. Então, é assim que
vamos realizar
o processo de instalação no Windows.
3. Como criar um arquivo do Docker: Tudo bem, agora que
temos o Docker instalado, vamos realmente usar Docker para que possamos executar
nosso aplicativo sobre ele. Agora, antes de entrarmos nisso, quero
mostrar rapidamente, em geral, onde vamos obter esses sistemas operacionais básicos são esses pacotes
básicos
pré-instalados que usaremos. Então, para fazer isso, você pode acessar hub.docker.com. Em seguida, você precisará
criar uma conta aqui. Então, se você não
tiver um, vá em frente e se inscreva nele. Você pode fazer login
e chegar a uma página que provavelmente é mais ou menos
assim. E você pode ir até
a seção Explorar,
se quiser. E aqui
já podemos ver uma lista de diferentes tipos de sistemas básicos
que estão disponíveis para nós. Isso pode ou não
significar nada para você. E podemos ver aqui o
python é um desses. Então, podemos
clicar diretamente nisso ou se estivermos procurando
por algo específico. Também podemos pesquisar
aqui, por exemplo, Python. E vamos usar
uma versão disso. E quando vemos aqui, podemos ver que existem essencialmente tags semelhantes
associadas a elas. E veremos em um segundo
como podemos usá-los. Mas todas essas são versões
essencialmente diferentes às quais temos acesso e que podemos usar. E a importância de usar tags é que elas fornecem uma
sensação de consistência. Se usarmos uma tag, poderemos reutilizar a mesma coisa de forma consistente
. E dessa forma, mesmo sejam
lançadas atualizações ou
algo parecido, sabemos que nosso sistema
não mudará. Ele sempre
funcionará exatamente
nas mesmas condições, que obviamente é
muito importante para nós. Então, para nós, vou
usar o Python aqui. Mas, apenas para sua informação se você precisar usar uma base ou
imagens diferentes do que se
não tiver certeza do que exatamente
está procurando, um rápido Google ou usando seu mecanismo de
pesquisa de escolha, provavelmente
direcionaremos você rapidamente
para a nossa direção, mas caso contrário, você também pode simplesmente navegar pelas imagens
disponíveis ao
público em um único local, basta acessar o Docker Hub. E você verá aqui,
por exemplo, para Python, essa é uma
imagem oficial e
geralmente é uma boa tag que
você deseja procurar. Uma vez que geralmente são
os mais confiáveis. Já que isso não vai
formar a base. E então você quer ter
certeza de que o que você instalou é como uma versão
adequada e não apenas feita por uma pessoa aleatória que pode ser um pouco
menos confiável. Embora a linha verde, a linha cinza nessa área, também se torne um
pouco questionável sobre o que, o que é confiável
e o que não é. Mas, geralmente, como
um bom indicador, a primeira coisa é
procurar as imagens oficiais. E quando não está, bem, não tem essa etiqueta. Apenas certifique-se de entender
o que está usando. Já que é nisso que você executará
seu aplicativo. Então, esteja ciente disso do ponto
de vista da segurança. Mas, dito isso, vamos voltar ao
nosso aplicativo. E o que vou
fazer aqui, vou criar um novo arquivo. E eu vou chamar
esse arquivo docker como
esse arquivo D Docker maiúsculo. Só vou pressionar Enter. E agora, aqui, vamos
criar nosso arquivo Docker. Então, a primeira coisa que
precisamos fazer é especificar o que deve formar
a base do nosso sistema. Então, essencialmente, a
maneira como criaremos esses contêineres
Docker, qual você pode pensar. Estamos enviando esses contêineres
bem estruturados, embalados e isolados,
quase como um estaleiro. Em cada um desses contêineres conterá, no nosso caso, como um aplicativo,
mas pode realmente conter qualquer coisa que esteja dentro. E parece
autossuficiente, ou pelo menos tem
tudo incluído que precisa ser incluído
em um único pacote. Então, a primeira coisa que
precisamos fazer é definir em que nossa base
estará. E, portanto, precisamos de algum
tipo de sistema operacional. Mas, geralmente, se
começarmos com um sistema operacional, isso se torna irritante porque
precisamos instalar todas as dependências extras do
Python para garantir que
possamos executar o Python. E uma coisa muito mais fácil de fazer é, em
vez de apenas começar ,
como começar em algum sistema operacional
básico e construir a partir daí, podemos dar alguns
passos adiante e podemos comece com um sistema operacional
que tenha o Python instalado. E então, tudo
o que precisamos fazer é instalar tudo o que precisamos e, essencialmente, executar
nosso aplicativo. Então é isso que vamos fazer. Vamos começar
com isso a partir da palavra-chave, que definirá com onde
queremos começar. Eu vou usar a imagem
do Python. E, especificamente, vou
usar a tag três pontos nove,
que, como você deve ter adivinhado, indica que isso é para a
versão 3.9 para Python. E então eu também vou
adicionar outro traço aqui e fazer a imagem
alpina. Agora, geralmente
é bom começar a construir
a
imagem alpina bom começar a construir
a porque é
relativamente pequena. O que você realmente não
quer é que você não queira
instalar um sistema
operacional massivo que tenha muitas
coisas instaladas, mas você não
vai usar muitas delas. Então, geralmente, a própria imagem
alpina com o Python será
suficiente para seus casos de uso. Mas se alguma vez não for, há outra
coisa chamada slim buster que você pode experimentar. Mas, alternativamente,
um rápido Google ou um rápido uso de seu mecanismo de pesquisa
favorito, seja ele qual for, o direcionará
rapidamente para a direção certa do que pode ser uma imagem melhor
para usar. isso. Mas, na maioria dos casos, a imagem alpina
será suficiente para você. E, novamente, o
benefício que
obtemos disso é que
não estamos apenas instalando um monte de coisas e que nosso
contêiner se torna muito grande. Mas, em vez disso, queremos
mantê-lo o
menor possível para que não
usemos muitos dos
recursos do nosso sistema apenas para ter todas essas coisas instaladas que nem estamos usando. Então, vamos começar com a imagem
do Python usando a tag 39 dash Alpine, que novamente é uma versão do
Python 3.9 e vem com tudo isso e as dependências pré-instaladas. E estamos usando a versão
Alpine aqui já que esta é
relativamente pequena. Tudo bem, então esse é o
primeiro comando que temos, que é o comando frontal. Agora vamos ver
o próximo comando, que
será um comando de execução. Então, aqui podemos usar
esses comandos para iniciar determinadas etapas. E a maneira como lidamos com as
coisas e Docker é cada comando
que temos em todos os lugares, cada palavra-chave
que você está usando aqui, você pode imaginar que está adicionando outra camada à sua imagem. Então, temos nossa primeira camada aqui. Agora, quando tivermos nossa
primeira palavra-chave aqui, run, que
veremos em um segundo. Vamos formar
nossa segunda camada. Temos outra palavra-chave aqui, digamos outra execução. Vou apenas
formar nossa terceira camada. E com isso, estamos
meio que construindo camada
após camada. Agora, a razão pela qual
isso é bom porque Docker também tem
alguma forma de cache. Portanto, ele reconhecerá
se você não fez nenhuma alteração em quase metade das suas coisas. E, na verdade, apenas a última
etapa é aquela que muda, então ele pode reutilizar a maioria
das coisas anteriores e só
precisa alterar a última camada. Portanto, mantendo isso em mente como
uma coisa muito importante, só porque quando você está
criando suas imagens do Docker, na
verdade, as coisas que
quase nunca mudam, você quer colocar no topo e as coisas que pode
mudar com mais regularidade, por exemplo, os pacotes que você precisa instalar ou também apenas
o código do seu aplicativo. Tudo isso deveria estar
mais voltado para o fundo. Tudo bem, mas estou começando com
esse comando de execução. Aqui, podemos pedir ao Docker que execute um comando específico e
você reconhecerá isso. Vamos executar
pip, instalar pip. Então, vamos
executar esse comando aqui, que você provavelmente reconhece
de uma lição anterior, onde vamos
instalar o pip end usando nosso PIP. E temos o PIP
disponível porque estamos instalando essa
imagem base do Python, que já tem o Python e as coisas que
precisamos para ele ou tudo está pré-instalado. versão do Python aqui
será 3.9 novamente, e também temos o comando
pipa man que vem imediatamente com ela. Então, sim, vamos
instalar o R assim. Agora, outra coisa que
vamos fazer é
criar um novo diretório. Vamos
criar uma nova pasta onde podemos guardar
todas as nossas coisas. Porque, em última análise,
estamos criando esse contêiner e queremos
colocar tudo o que
precisamos em um único local para
que esteja disponível para nós assim como o temos aqui
em nosso arquivo de projeto, por exemplo, e assim para fazer isso, usaremos esse diretório
MK para o diretório make. E
teremos esse menos p,
que essencialmente nos permite
criar várias pastas ao mesmo tempo. E então vamos usar esse aplicativo de barra SRC do usuário path. E é aqui que
colocaremos todo nosso código em nosso aplicativo. Agora, essas coisas, eu não quero entrar em
muitos detalhes com todos os comandos do Linux
porque, na verdade, há um curso separado sobre isso. Então, não quero
descarrilar um pouco demais aqui e realmente
focar nisso. Mas, basicamente,
tendo em mente aqui, e você pode simplesmente reutilizar a
sintaxe, é que estamos apenas
criando esse diretório aqui e estamos criando
essas pastas. Então, na pasta do usuário, temos a pasta SRC e aí temos
o aplicativo. E se algum desses não existir, nós o criaremos. Então, estamos fazendo isso de novo, só para que tenhamos uma pasta na qual possamos colocar nossas coisas. A próxima coisa que
faremos é usar um novo comando chamado loops work. E isso definirá nosso diretório de trabalho
atual. Isso vai
nos ajudar porque, em
vez de sempre ter que
digitar isso em todos os lugares, sempre que
quisermos executar algo ou, em um segundo, veremos
copiar algo. Podemos apenas dizer usando
nossa localização atual. Então, isso só vai facilitar
um pouco para nós
, para que não precisemos repetir
este ano o tempo todo. Então, vamos
vendê-lo para esse usuário do aplicativo SRC. Esse será o nosso diretório de
trabalho ou a pasta em que estamos trabalhando
atualmente, na qual tudo deve
estar em relação ao correto. Então, agora que temos o pip instalado, temos a pasta na qual vamos colocar
nossas coisas. E também vamos
apenas definir uma localização relativa para isso. Agora, o que precisamos fazer é
ter acesso aos nossos arquivos, mas queremos copiá-los em nossa imagem e colocá-los
no local certo. Vamos usar
esse comando de cópia. E agora precisamos ver
o que temos aqui. E, essencialmente,
queremos agora copiar isso. E queremos ter
a mesma estrutura na maior parte
do tempo aqui, exceto talvez nos livrarmos de parte do lixo de
que não precisamos. Então, vamos fazer
isso em duas etapas. Vamos começar com o bloqueio do arquivo pip
e o arquivo pip, bem
como esse main.py. Como esses são os
que estão mais lá fora, eles estão meio que
um nível acima. Então, vamos
copiá-los. Então, vamos
copiar nosso arquivo pip,
nosso arquivo pip dot loc. E também
copiaremos nosso main.py. E vamos usar isso porque, em vez de
ter que escrever o aplicativo SRC do usuário de caminho completo para o
qual queremos copiá-lo, porque definimos nosso diretório de
trabalho, podemos simplesmente usar
o caminho relativo, o que significa copiado para o diretório de trabalho
atual. Então, isso vai ser
copiar, pegar isso, e vai ser
copiar isso para nós. Tudo bem, agora que copiamos
esses arquivos, agora queremos copiar tudo na pasta do nosso
aplicativo aqui. Agora, infelizmente, não podemos simplesmente adicionar nosso aplicativo aqui porque ele pega todo o
conteúdo de dentro e o copia
na mesma camada, o que não é o que queremos. Então, vamos adicionar uma
segunda etapa de cópia aqui. E queremos copiar
o conteúdo do nosso aplicativo basicamente em
uma pasta de aplicativos. Então, o que vou fazer é criar uma outra pasta de aplicativos aqui. Portanto, nossa estrutura
de pastas será sua pasta principal é o usr, então vamos para SrC. Depois, temos a pasta do aplicativo
e, dentro dela, temos
outra pasta do aplicativo. Então você pode imaginar isso apenas com o nome dessa pasta,
em vez de serem ofertas, compre-as, o projeto
estaria pronto e
temos o aplicativo aqui e o aplicativo aqui. E agora eu queria copiar o
conteúdo dessa pasta, que é app, para a
pasta de aplicativos encontrada aqui. Tudo bem, então copiamos
nosso material de primeiro nível aqui. Vai ficar
na mesma camada. E agora eu quero ter certeza de
que todo o conteúdo e aqui também estão nesse formato. E, novamente, se eu apenas usasse
isso, isso vai pegar o
conteúdo daqui e simplesmente
copiá-lo para o mesmo nível, que obviamente não é a estrutura
atual que temos. Para fazer isso, vou adicionar outra pasta aqui para a qual
possamos copiá-la. Tudo bem, agora
que temos isso, vamos em frente e, por enquanto, apenas aprender como podemos
começar nossa imagem e examinar nossa estrutura atual para ter certeza de que está tudo bem. E então o que
vamos fazer é terminar com o resto
das coisas que serão instaladas
usando a instalação pip e também
executando nosso servidor. Mas, por enquanto, vamos dar uma olhada em nossa estrutura atual e
ver se ela é adequada. E para isso, vou
usar o ls menos l, que se você estiver em um Mac ou Linux, deve funcionar para você. Eu não acho que isso
funcionará em um Windows, mas tudo bem porque
funcionará aqui porque
vamos usar uma versão baseada em Linux de qualquer maneira. Mas você pode ver o que
esse comando faz é imprimir o conteúdo contido na pasta
atual em que estou. Então, essencialmente, podemos
ver aqui que o conteúdo aqui é exatamente igual ao
conteúdo listado aqui. Então, vou
executar isso por enquanto,
só para que possamos
dar uma olhada em nossa imagem que estamos construindo aqui para ter certeza de que
nossa estrutura está correta. Tudo bem, agora que temos
nosso arquivo Docker definido, que define o conjunto de etapas
que vamos seguir, começando com uma imagem base e copiando todas as nossas coisas até ter essa imagem que contém tudo
o que
precisamos para que possamos realmente
executar nosso aplicativo. Ainda não tem tudo, mas estamos chegando lá. Então, agora que temos que
fazer é agora que
temos essa imagem para encontrar aqui, precisamos construir essa imagem. Portanto, não precisávamos executar
esses comandos e colocar
tudo em um pacote pronto
que podemos simplesmente executar. Então, para fazer isso, vamos usar o
comando chamado Docker build. E agora vamos
usar um t menos aqui, que será o alvo
para o queremos copiar isso, o nome que queremos
associar a isso. E aqui vou chamar isso
de meu primeiro aplicativo. E eu vou dar uma reviravolta
na etiqueta, mais recente. Agora, latest é uma tag que você verá com
frequência, que é. Apenas indica que esta é a versão mais recente
desta imagem. Agora, normalmente, o que você
terá é ter uma tag associada a cada imagem
e, em seguida, você também
tem uma tag mais recente. Dessa forma, se você quiser apenas executar
a versão mais recente, poderá usar a tag mais recente, que provavelmente mudará com tempo se as atualizações
estiverem sendo aplicadas. Dessa forma, você tem
a garantia de estar sempre na versão
mais recente. Ou você também pode
referenciar uma tag específica, como estamos fazendo
neste caso aqui, que significa que mesmo quando mais de 3,10 é
nosso, então é 3,11, 13,12, 13
se isso sair ou quando o preço
e o quatro forem lançados, isso não vai nos
impactar, porque ainda
vamos
ficar com imagem
específica
rotulada com essa tag aqui. Portanto, isso nos garante a consistência de que, mesmo que
as coisas mudem, sempre
usaremos a mesma base. Então, obviamente, existem
prós e contras de cada um. Com isso, você pode facilmente
acompanhar a
versão mais recente sempre que estiver iniciando
ou reconstruindo. Mas, obviamente, elas também são ressalvas, porque
se as coisas
mudarem, elas podem se tornar incompatíveis e suas coisas
podem não funcionar mais, o que obviamente não é bom. Então, tendo isso em mente, agora temos a
meta na qual
queremos dizer, incorporar isso. Agora só precisamos fornecer a
localização do nosso arquivo Docker, que eu vou
colocar o ponto aqui, que só vai
indicar que ele está
na pasta atual em que
estamos atualmente. Vou pressionar enter. Agora, para você, isso provavelmente vai levar um
pouco de tempo pois você precisa primeiro
baixar esta imagem. E então você vai executar todos esses comandos em cima dele. Para mim, muitas coisas
já foram descontadas. E você pode ver aqui,
se rolarmos para cima, muitas dessas etapas
foram descontadas. E, portanto, não há nenhum
download real sendo feito para mim. E, na
verdade, o processo de construção é
muito, muito rápido, como podemos ver. Depois de executar isso
pela primeira vez, se você executá-lo novamente,
também será muito rápido. Porque, novamente, essas
camadas são armazenadas em cache. Então, agora que criamos
nossa imagem, agora queremos executá-la. Então, temos esse pacote que está pronto e agora queremos executá-lo. Então, para fazer isso,
vamos usar o comando docker run. E
agora vamos fornecer o nome e a
tag que queremos executar. Então, queremos executar
essa imagem aqui. E eu também vou
atribuir um nome a ele. Então, vamos executar
isso, e isso vai
funcionar como um contêiner. Vamos exibir essa
imagem aqui como um contêiner. E vamos
dar um nome a esse contêiner em execução para
que possamos vê-lo melhor. Isso podemos, quando
observamos quais
coisas estão funcionando, o que veremos
em um segundo. Nós saberemos, ok, isso
é, esse não é um. Então, podemos dar
um nome legível a ele. Então, vamos chamar isso nossa
primeira aplicação, talvez sublinhada. Você não precisa dos sublinhados, mas eu vou usá-los. E sim, basta pressionar enter aqui. E vamos
executar isso e podemos ver que ele executou
esse comando aqui, que está apenas
listando o conteúdo. E a estrutura que
temos é o arquivo pip. Temos o arquivo pip dot loc. Temos a pasta do aplicativo, que dentro deve
conter todas essas coisas. E temos o main.py. É assim que nossa pasta atual
se parece com a que temos. Agora, isso é bom porque
não temos os testes, por exemplo porque não precisamos do
teste se estivermos executando nossa imagem ou para executar
esse código como um aplicativo. Porque até lá, ou nossos
testes, eu já executei e não precisamos mais dos testes lá, porque
não vamos
executá-los como um aplicativo ativo. Vamos executar o teste quando estivermos
testando localmente, vamos executar os
testes mais tarde, quando estivermos, antes de criarmos nossa imagem. Depois que nossa imagem é criada, não
precisamos mais dos testes. E então podemos descartar
isso e dizer, economizemos um
pouco de espaço aqui também. Então, agora que
temos isso em execução, vamos continuar
com nossa configuração aqui. Porque, na verdade,
não queremos apenas imprimir o conteúdo e
depois acabar com ele. Mas, em vez disso, queremos ter um aplicativo em execução
que possamos realmente usar. Para fazer isso, ainda precisamos
dar alguns passos. A primeira coisa
que precisamos fazer é executar nossa instalação do pip que possamos
instalar toda a dependência de
que precisamos. Então, vamos usar nossa
instalação pip . Não vamos usar
a tag def porque essa será essencialmente nossa
imagem de produção. Portanto, não queremos instalar as dependências de desenvolvimento
porque não precisamos delas. Seremos apenas
uma aplicação pura. No entanto, vamos
usar uma nova tag que será dash, dash system. Agora, isso instalará
tudo o que estamos usando todo o sistema para que executemos ou, quando estamos tentando acessá-lo, não
precisemos entrar em
nosso ambiente virtual, mas é só
será
instalado em um sistema inteiro, o que
tornará tudo um pouco mais fácil para nós
, porque então não precisamos usar o PIP e o
comando mais tarde novamente, porque essencialmente
o que temos em toda essa imagem aqui é
um ambiente virtual. Estamos recriando isso
todas as vezes e não há
mais nada acontecendo. Assim, podemos instalar esse sistema em todo o sistema porque
sabemos exatamente o que é, porque estamos
construindo tudo. Do zero. Então, vamos instalar nossas dependências,
como costumamos fazer. E agora, o que precisamos
fazer é realmente executar nosso aplicativo. Então, usaremos o
comando CMD novamente para isso. E vamos abrir
e fechar parênteses. E cada uma das entradas
são cada um dos elementos que teremos aqui será um dos argumentos
que vamos executar. Então, por exemplo, geralmente quando
executamos o aplicativo unicorn main dash, que você pode realmente
executar assim. Mas a forma preferida de
escrever isso seria assim. Então, se fizermos isso,
esse
será o comando usual
que usamos, exceto que geralmente também temos
essa tag reload, whoops. Não queremos usar
isso na produção
porque isso diminuirá muito a velocidade da aplicação. Portanto, certifique-se de não
usar essa tag na produção. Quando o executamos
localmente, tudo bem. Isso torna o processo
muito mais fácil. Mas quando eu o estou executando
na produção, você não quer mais
usar essa tag. Então, agora podemos
continuar assim , se
quisermos, podemos experimentá-lo. Mas ainda há
alguns problemas que veremos em um segundo com isso. Mas vamos chegar até eles
quando chegarmos a eles. Então, o que vou fazer é
reconstruir
minha imagem novamente e depois entrar no
meu primeiro aplicativo, o mais recente. Então, vou
sobrescrever essa tag usando o comando docker build. E opa, esqueci
o ponto negativo aqui. Então, neste caso, vai demorar um
pouco mais porque agora realmente precisamos executar
esse sistema de instalação pip. Então, anteriormente,
não executávamos isso, mas agora estamos executando. E, portanto, ele precisa realmente executar esse processo que
precisa ser baixado, instalar todas as dependências até o momento, será um pouco mais lento, mas podemos ver todas as etapas
anteriores aqui, estamos na verdade, são armazenados em cache e, portanto, são
muito, muito rápidos. E uma vez feito isso, o que deve ser feito
em apenas um segundo. Sim, lá vamos nós. Então, agora que temos isso dividido, podemos executar o Docker. E vamos dar nosso nome, que será
meu primeiro aplicativo, o mais recente. E vamos reutilizar o mesmo nome, que será
nosso primeiro aplicativo. Queremos dar
o crachá aqui. Vamos ter
um problema aqui porque ele está reclamando que esse
nome já está em uso. E resolveremos esse
problema em um segundo. Mas, por enquanto, vamos
usar um nome diferente, por exemplo, como este. Esse nome agora é
diferente desse. Então, deve ficar bem. Mas abordaremos esse
problema em apenas um segundo. Então, vamos seguir em frente e executar isso. E isso
será, podemos ver aqui o comando que normalmente
vemos, nosso aplicativo
que
está sendo iniciado. Mas agora
é o seguinte. Se tentarmos acessá-lo, clicaremos aqui. Na verdade, não
temos acesso a ele. que obviamente é péssimo
porque, idealmente ,
mesmo localmente,
queremos poder realmente usar o Docker para
fazer nosso desenvolvimento. Dessa forma, podemos
ter certeza absoluta de
que o que estamos
executando localmente em nossa máquina é
exatamente o que será executado
na nuvem posteriormente. Não teremos problemas de coisas
não
estarem instaladas corretamente ou não estarem disponíveis. Então é isso que
vamos ver agora. Tudo bem, então eu sou atingido aqui, controle C para matá-lo. E agora, o que
vou fazer é, primeiro, usar
essa tag de host de traço, traço. Então, em vez de
executá-lo em 127 pontos,
ponto zero , ponto um, em vez disso,
vou executá-lo em 0000, que significa apenas que isso
aceitará qualquer interface
que esteja vindo, o que a torna mais
geral, o que é, novamente, bom porque não queremos
especificar um endereço específico, mas essencialmente queremos
apenas fazê-lo, desde que estejamos aqui, queremos ter acesso a ele. Então, vamos usar
esse host em vez disso. E agora também o que
vamos fazer é
definir uma porta específica que queremos usar
para fins de consistência. Então, eu vou usar a
porta 80, 80 aqui, por exemplo, mas você também pode usar outras
diferentes. Mas, neste caso, vou usar
a porta 80, 80. E agora, se reconstruirmos nossa imagem, basta rolar para cima e reconstruir e esperar que
esse processo termine. Você vê que a maioria das nossas
camadas está armazenada em cache porque a única alteração que
fizemos foi realmente aqui. Todo o resto
já foi feito. E então, essencialmente, recarregamos
todas essas etapas a partir do dinheiro. E agora vou
atribuir um novo nome por enquanto, já que temos essa
colisão de nomes anteriormente, que veremos em
um segundo e clicaremos em Executar. Tudo bem, agora podemos
ver que aqui estão sendo executados neste host e estamos
rodando nessa porta. Mas ainda assim, se eu for aqui, ainda não
conseguiremos acessá-lo. E isso porque nosso
aplicativo está sendo executado dentro desse contêiner e
atualmente não tem acesso ao mundo
exterior, mesmo em nossa própria máquina. Então, o que precisamos fazer é,
em nosso comando docker run, eu vou usar
o sinalizador menos P. E isso
nos permitirá fazer o encaminhamento de portas. Quando saímos de nossa máquina e olhamos de nossa porta, ela a
encaminhará para uma porta específica em nosso contêiner em execução, por exemplo, vou dizer a porta de encaminhamento 808-02-8080 no recipiente. E dessa forma agora, quando eu executo esse nome
já existe, você tem que mudar
esse nome por enquanto. Quando eu vou aqui. Agora ele estará disponível. E podemos ver se
vamos para a página de documentos, teremos os documentos disponíveis para nós porque estamos na porta 80. 80, que na verdade agora é encaminhado para o porto do contêiner. Agora, para mostrar isso novamente, vamos usar alguns números
diferentes aqui. Vamos usar a porta 8.000, que vamos encaminhar
para a, opa, não era isso
que eu queria. 8.000, que serão
encaminhados para os portos 80,
80 e nosso contêiner. Portanto, lembre-se de que, em nosso
contêiner, o aplicativo está sendo executado na porta
80, 80, mas do lado de fora, vamos encaminhá-lo
da porta 8.000. Então, se eu executar isso,
adotei o nome novamente. Estou executando isso. Se eu clicar aqui, agora teremos um problema porque não há nada em
execução na porta 80. 80. Mas se eu usar a porta 8.000 , seremos
encaminhados para a porta 80,
80 dentro do nosso aplicativo. Então, isso não é importante. Opa, mostre o comando novamente. Esse é um
passo importante que precisamos
dar porque vamos
encaminhar o que
temos em nossa máquina, na verdade nos permitindo
entrar no contêiner. Tudo bem, então agora vamos abordar esse problema
de nomenclatura aqui. Se usarmos esse
comando docker ps, podemos realmente examinar todos os contêineres
atuais em execução, que atualmente não existem. Mas se eu executar este de
novo, o nome novamente. Tudo bem, se eu executar
este novamente, abro um novo terminal aqui. E espere que isso termine
de se preparar. Vou sair do
meu ambiente virtual. Agora, se eu usar o comando novamente, docker ps, podemos ver aqui que temos o único contêiner
em execução. Podemos ver aqui que
esse é o comando que está sendo executado internamente. Esse é o encaminhamento de portas
que estamos realizando. Esse é o nome
do contêiner em execução. Quando foi criado. O Stata é que temos que adicionar
a imagem que está rodando. Assim que matarmos. Isso. Posso
ver aqui agora que também desapareceu. Mas se quisermos analisar todos os contêineres disponíveis, voltaremos ao
nosso terminal anterior. Podemos usar esse docker, ps dash, dash all, que nos mostrará
todos os contêineres que temos. Então, podemos ver aqui, este é o primeiro
que criamos. Então temos o segundo, o terceiro, o
quarto, o quinto 161. Então, o que podemos fazer é se
tivermos esses contêineres antigos, em vez de ficarmos sentados
lá ocupando espaço, podemos realmente
excluí-los se quisermos, o que podemos fazer
usando o docker remove. E então vamos
especificar o ID do contêiner aqui. Então, vou pressionar Enter e ele removerá isso para que possamos ver se
eu imprimo novamente. Este agora desapareceu. E eu vou fazer isso
por este também. E vamos também fazer isso. Vamos imprimir esses
novamente aqui. E para tornar isso um
pouco mais rápido, vamos remover vários. Lá vamos nós. Imprimindo esses. Agora podemos ver que temos apenas cinco sobras de
nosso aplicativo, que também não está mais em execução. Então, se quisermos
excluir este, também
podemos remover o docker. Então, agora não temos contêineres
e o AlphaGo volta para, por exemplo, ou execute o comando. Podemos reutilizar o mesmo nome porque
não há nenhum contêiner associado a ele
no momento. Agora, novamente,
vai funcionar. entanto, ainda existem alguns outros
comandos aqui que você provavelmente
usará um deles. E o que vou
fazer aqui é unir
dois comandos. Então, na verdade, primeiro preciso obter o ID do
contêiner e
vou removê-lo. Tudo bem, então veremos isso
em um segundo. Mas primeiro, uma coisa que provavelmente faremos é
o que não queremos é que
nosso terminal seja bloqueado por isso, porque ainda
queremos poder
fazer outras coisas. Então, há um voo
que podemos usar, que é esse menos d, que o
executará como um processo daemon, que significa que ele só
será executado em segundo plano. Não vai destruir
esse espaço do terminal em primeiro plano. Então, se executarmos isso, podemos ver aqui agora
se fazemos docker ps, temos um contêiner em execução. E se acessarmos nosso navegador da web, eu clico em atualizar aqui,
então podemos ver. Que nosso aplicativo
está de fato em execução. Esses eram
os outros, então
vou fechá-los. Este também não deve estar em execução porque é
extremamente importante. Então, agora vamos meio que
correr em segundo plano. Então, agora a pergunta
pode ser: como podemos impedir que ele seja executado anteriormente, poderíamos pressionar o
Controle C. O que podemos fazer agora é usar
o comando docker, matar e fornecer o ID do
contêiner, pressionar Enter. E agora, se tentarmos novamente, nosso aplicativo
não estará mais em execução. podemos ver aqui nenhum contêiner
em funcionamento. Mas ainda tenho o
contêiner disponível. Então, vou remover esse. Assim. Também podemos fazer isso usando a interface do usuário do
desktop, se quisermos. Então, se puxarmos esse
aqui e agora executarmos nosso contêiner assim,
voltaremos para a interface do usuário. Podemos ver aqui agora que
temos um contêiner em execução. Se quisermos,
podemos clicar nele. Na verdade, podemos ver
a saída aqui. Há algumas coisas
com as quais
você pode brincar, se quiser. Sempre que estivermos prontos. Quero dizer, vimos como podemos simplesmente
fazer isso pelo terminal. Se você quiser
usar a interface, se quiser pará-la, por exemplo, você pode clicar em Parar aqui, o que
impedirá que ela seja executada. Então, se você tiver docker ps, podemos ver que
não há contêineres em execução ou fazer docker ps
menos, menos todos. vê que o contêiner ainda
está disponível? E se clicarmos em Excluir aqui
, por exemplo, também
excluiremos nosso contêiner. Então esse foi nosso primeiro
olhar sobre o escuro. E eu sei que cobrimos muita coisa. Mas chegamos a um ponto
muito bom porque agora podemos realmente executar bem
todo o nosso código, exceto para fazer alterações , quando
ainda precisamos reconstruir. Mas podemos realmente executar nosso aplicativo
em uma imagem do Docker, que é incrível porque
essas serão as especificações exatas
que serão
executadas quando ele estiver sendo executado um
ambiente de nuvem em algum lugar. E, portanto, sabemos que tudo o que
está sendo executado aqui é essencialmente como
funcionará quando estiver
sendo executado em outro lugar. O que é extremamente bom
porque agora temos muita consistência em nosso sistema e não precisamos nos
preocupar com o quão k, mas ele roda na minha máquina. Será que vai realmente rodar
em outro lugar? Se estivermos usando imagens do Docker
, sabemos que,
mesmo que queiramos
dar isso a um colega,
ele pode baixá-las. Eles podem criar a
imagem do Docker que pode executá-la. E eles vão ver
exatamente as mesmas coisas que nós temos. Agora. Obviamente, o Darker é
um software muito legal e há muitas
coisas que vêm com ele. E não vamos
cobrir todos eles. Também vamos
analisar o Docker Compose. Então, há algumas coisas que
podemos fazer no escuro que não
vamos analisar aqui,
porque algumas das coisas que faremos
usando
o Docker compõem, por exemplo, mas mesmo com isso,
obviamente há muitas coisas básicas em
que você pode se aprofundar. Algumas coisas muito sofisticadas
e complexas para ter um sistema realmente legal. Mas para a maioria, quase todas as
intenções e propósitos, que estamos fazendo
agora é essencialmente o
que estamos fazendo
agora é essencialmente o que você
vai precisar deles ou você vai fazer quando
estiver realmente construindo e funcionando aplicações
em acompanhamento. E se você precisar de coisas
específicas, se deparar problemas
específicos do que o Google ou qualquer que seja o seu mecanismo de
pesquisa favorito, provavelmente o ajudará o mais rápido, porque você sabe exatamente o que você está procurando, as coisas básicas do que você pode fazer e, em seguida, você
pode rapidamente Há algumas coisas por aí. Mas sim, mais escuro novamente, é coisa
muito, muito importante,
muito comum. Todo o meu código que estou
executando essencialmente
será executado com
mais escuro e de alguma forma porque é
muito bom ter
a consistência de ter essa imagem que
podemos simplesmente implantar em algum lugar e eu sei exatamente
como isso vai funcionar. E você pode
entregá-lo a um colega e ele pode executá-lo em
sua máquina e você sabe que tudo o que eles
têm será exatamente
a mesma configuração
que você tem. E, portanto, é
muito bom porque permite consistência
e reprodutibilidade.
4. Construção em vários estágios: Então, anteriormente,
vimos como podemos criar nossas imagens do Docker. Agora, nesta lição,
abordaremos
algumas das melhores práticas e a adaptação é possível
fazer com essa imagem do Docker
que estamos criando com esse
modelo de imagem do Docker que estamos criando para criar um
recipiente retirado de. E, essencialmente,
isso é algo que você provavelmente verá
usado em muitos, muitos lugares. E, em geral. Em primeiro lugar, como uma observação
rápida, você provavelmente verá que,
se estiver usando o PyCharm, receberá algum tipo de
solicitação de instalação de plug-in para o Docker. Se você quiser,
basta clicar em instalar o plugin. Haverá como uma
barra azul e eu vou apenas adicionar algumas formatações, pois você pode
ver que eu a tenho aqui. Mas se você não quiser, basta
clicar em Ignorar. Mas, apenas como uma nota
lateral rápida, você
provavelmente verá aquela barra pop-up. Mas, de qualquer forma, para
essas melhorias, você verá muito
isso. E
veremos se primeiro vamos criar um usuário. Esse usuário vai
nos ajudar porque, no final, não
queremos executar todo
o nosso sistema como usuário root. Mas, em vez disso, se o executarmos como um usuário com
privilégios reduzidos, isso pode nos ajudar. Porque se nossa imagem Docker
ou um contêiner
Docker for atacado, aquele usuário que hackeia não terá acesso
total ao sistema, mas terá
acesso reduzido, o que é bom. A outra coisa que
vamos ver é uma construção de vários estágios. E isso só
nos ajuda a reduzir
o tamanho da imagem final
que vamos executar, que só ajuda a
manter as coisas menores. Então, sim, e apenas
como uma nota geral, para essas coisas mais sombrias, vamos passar por
isso passo a passo para que você entenda
o que estamos fazendo. Mas na maioria das vezes você vai ter
algum tipo de modelo. Se você está trabalhando
em uma organização, provavelmente pode ter
certeza de que eles têm algum tipo de modelo
Docker que você
pode usar para trabalhar. Se eles não tiverem
um oficial, basta olhar para
outro repositório e usá-lo como um
modelo e meio que adaptado ao que você precisa. E, alternativamente, se você
sabe o que está procurando, há muitos modelos de ferramentas
on-line que você pode usar para não precisar memorizar essas coisas de cor. Você provavelmente
usará modelos para isso. Você meio que precisa saber o que quer, por que está lá. E se faltar alguma coisa, acrescente isso, essencialmente. Então é isso que vamos passar do zero. Mas, na maioria das vezes,
quando você está fazendo isso, você mesmo pode escrever. Mas também é
fácil usar um modelo porque, na maioria das vezes, você fará coisas muito
parecidas. Tudo bem, então vamos
começar adicionando nosso usuário. Então, vamos adicionar
outro comando de execução aqui. E vamos adicionar
grupo menos S. Para adicionar isso, vamos criar um
grupo ao qual adicionaremos nosso usuário
em um segundo. Vamos adicionar
isso ao nosso sistema. E eu vou
chamar esse grupo de meu aplicativo, mas você pode chamá-lo de qualquer coisa. Em seguida, usamos isso e, e que nos permite
encadear comandos juntos. Então, primeiro vamos
executar este, e agora vamos executar outro comando depois deste, que será adicionar usuário. E também faremos
disso um usuário do nosso sistema. Vamos adicioná-lo
ao nosso grupo de meus aplicativos. Vamos dar a esse
usuário o nome de usuário e também
atribuiremos um ID para ele. Vamos fazer 1234. Agora, se quisermos executar
tudo como usuário, usaremos esse comando de usuário do
Docker. E então podemos
dar o nome aqui que atribuímos
ou veremos em um segundo, todos
veremos que é o ID. E o que isso
fará é procurar esse
usuário no sistema, e ele vai encontrar esse ID. E então, o próximo comando ou ponto de
entrada que temos, ele será executado usando
esse usuário em vez disso. O que é bom, porque então não
estamos mais executando isso como o usuário root
que tem acesso total, mas sim com acesso reduzido. Então, vamos seguir em frente e
garantir que isso funcione. Vamos fazer a primeira compilação do
Docker menos t. Faremos a versão mais recente do meu aplicativo. E, na verdade, também
vou usar isso e entregar aqui para que você possa
ver o que ele faz. Mas, essencialmente,
primeiro executamos isso. E se, se isso for bem-sucedido, executaremos
a próxima coisa aqui. E isso vai
ser docker, corra. Assine um nome, meu teste de AP. E podemos mapear as
portas como aprendemos anteriormente e a imagem
que vamos executar meu aplicativo, mais recente, que será
essa aqui. Pressione Enter. Agora, isso deve ser relativamente
rápido porque as coisas devem ser armazenadas em cache e adicionamos apenas mais
dois comandos
na parte inferior aqui, podemos ver aqui que o
processo de construção foi muito rápido. E aí vamos correndo, e está funcionando corretamente. Tão excelente. Tudo bem,
vamos em frente e desligar isso. Controle C. E sim, vá para a parte de construção de
vários estágios. E aqui vamos
adicionar mais algumas mudanças, que veremos daqui a pouco. Então, a primeira coisa
que vamos fazer é manter
isso fora do comando. Na verdade, vamos
atribuir um alias a ele e chamaremos isso de nossa base. E aqui,
basicamente,
faremos nossa instalação
e nossa configuração. E daqui a
pouco, como veremos, copiaremos
as coisas
dessa base que criamos para nossa imagem principal
em execução. E agora, tudo que não será
o mais recente que estamos usando será apenas temporário e depois
será descartado, que é bom porque isso significa tudo o que não inserirmos em nossa imagem final será descartado e não
ocupará nenhum espaço. Tudo bem, então estamos criando
nossa imagem base aqui. Então, agora a primeira coisa
que queremos fazer ainda
é instalar o pip nth. E agora, em vez de ser a primeira coisa
que queremos fazer ou todo
o
objetivo dessas imagens básicas, essencialmente queremos
instalar algumas de nossas coisas. Então o que eu
vou fazer é pegar isso aqui, eu vou cortar Eu vou
colocar isso aqui. Mas eu não preciso do arquivo
principal agora porque eu só quero o bloqueio do nosso
arquivo pip e do nosso arquivo pip. Porque eu só quero
fazer a instalação. Por enquanto, vou criar um comando de cópia extra aqui embaixo. E eu vou pegar essa
parte e movê-la para cá, e vamos falar sobre isso mais tarde. Então, agora eu
vou apenas copiar o arquivo ou pip e, em seguida, bloquear o arquivo pip. Como alternativa, o que podemos
fazer é usar o arquivo pip star, que procurará qualquer coisa que
corresponda a esse formato. Então, qualquer coisa que tenha um arquivo
pip antecipado e , em seguida, qualquer arquivo que tenha
algo depois disso. Então, por exemplo,
vamos combinar o pip e o arquivo pip dot loc. E se tivéssemos
outro como arquivo pip, arquivo, isso também seria
igualado por isso. Mas isso, opa,
eu não queria isso. Podemos usar esse
ou outro. Mas isso é apenas uma abreviatura. Tudo bem, então estamos
copiando nosso arquivo pip. E agora, a próxima coisa
que queremos fazer é realmente executar essa instalação. Porque queremos executar essa imagem
criada e nossa imagem base. E depois
copiaremos
os arquivos instalados para que não
tenhamos nenhum, nada mais. Tudo bem, então vamos
manter uma sintaxe similar, mas mudar um pouco as coisas
. Então, vamos manter
nosso pip para instalar. Vamos fazer uma instalação em
todo o sistema. Rocks adicionarão
outro voo aqui, que
será a bandeira de implantação. E se você quiser saber o que
essas bandeiras fazem especificamente, podemos, porque
temos o pip instalado, podemos ir pip install menos h. E isso realmente vai
abrir uma busca de ajuda, o que lhe dará todos os
comandos acessíveis. Assim, podemos ver se
vamos ao sistema, por exemplo vamos instalar isso apenas em nosso
sistema ou implantar. Então, isso vai
ser bom porque essencialmente, se
algo estiver errado, como nossos arquivos de log desatualizados ou a versão do Python estiver errada,
isso será abortado. O que é bom porque só
queremos ter certeza de que tudo
está funcionando conforme descrito. Então, se algo
está errado aqui, vai simplesmente abortar. E então vamos adicionar outra bandeira que será ignorar loops de arquivos pip. O que significa que vamos construir
especificamente a partir da eclusa. Tudo bem, então essa
será a nossa instalação do pip, que é um pouco diferente, mas ainda muito semelhante
à que tínhamos antes. Ainda há algumas
mudanças que
precisarão ser feitas aqui em um segundo, mas as abordaremos
quando chegarmos a isso. Agora vamos adicionar outro
de e
extrair exatamente a
mesma imagem aqui. E então aqui. Agora vamos, bem, queremos copiar. O fato é que já
instalamos aqui anteriormente para que
todos os pacotes que instalamos
sejam
copiados para nossa imagem principal, da qual
precisaremos. Agora, para fazer isso corretamente, há várias coisas
que precisamos fazer. Então, primeiro de tudo,
vamos adicionar algumas variáveis de ambiente,
que, na verdade, para o Docker, podemos usar essa palavra-chave
final que definirá
variáveis de ambiente para nós. Então, a primeira variável de
ambiente que
vou usar será nossa raiz pi. E eu vou
defini-lo para ter esse valor raiz de barra pi. E isso
basicamente acontecerá,
vamos usar isso
em um segundo para dizer onde queremos que as coisas também sejam
instaladas. Em seguida, vamos criar uma variável de base de usuário do
Python. Agora, essa variável é importante
porque nos
informa ou informa ao sistema o
diretório base do usuário. E vamos definir esse valor
para essa variável de
ambiente pirata. E eu posso referenciar o valor contido nessa variável
usando o cifrão e
depois o nome da variável. Se eu quiser, também posso colocar
isso entre colchetes, o que pode ser útil
se houver outras coisas
anexadas posteriormente. Então, agora o que fizemos foi definir essa
variável de ambiente com esse valor. E definimos
essa
variável de ambiente para o valor
contido aqui. Agora vamos usar
mais uma variável de ambiente, que será o caminho. Agora, com o caminho
é, é essencialmente uma lista de lugares onde nosso sistema operacional
procurará executáveis. E como vamos instalar neste
diretório aqui, queremos ter
certeza de adicioná-lo à lista de arquivos detectáveis
para procurar executáveis. Para. Então, para fazer isso, vamos referenciar
nossa variável de caminho existente e
adicionaremos a ela nossos piratas. Diretório de compartimentos de barras
especificamente porque é aqui que nossas
cutículas de execução viverão. Agora, novamente, como
mencionei anteriormente, você não precisa entender
isso de dentro para fora. Você não precisa ser capaz de
reproduzir isso pela memória. A questão é que você entenda por que estamos
fazendo essas etapas. Aqui. Estamos adicionando isso porque precisamos ter algum tipo de diretório de usuário
básico para onde
nossas instalações irão. E agora, como estamos
adicionando instalações, também
queremos garantir que os executáveis possam realmente ser encontrados pelo sistema operacional. Esses são essencialmente os passos
que estamos tomando aqui. E se não tomarmos
essas medidas, você verá. E podemos tentar isso em um segundo. Não vai funcionar.
Portanto, é importante adicionemos essas etapas para
que elas funcionem corretamente. E tudo o que estamos fazendo aqui é apenas criar variáveis de
ambiente. Tudo bem, então temos
nossa instalação de
pip, pip end, que
vamos manter a mesma. Então, ainda queremos
instalar o pip end. Vamos copiar
nossos arquivos Pip. E agora vamos adicionar mais
uma bandeira na frente daqui. Ou vamos definir nossa variável de ambiente
para esse comando. E vamos definir
aqui a
variável de ambiente do usuário para querer uma. O que significa que tratará essa instalação como
uma instalação do usuário. que significa essencialmente
o material de localização do usuário que definimos acima. Eu vou fazer efeito. Então, acabamos de atualizar isso para agora tratá-lo como uma instalação
do usuário. E essa é a primeira parte. Então é nisso que nossa base
consistirá. E, novamente, o objetivo está aqui, é fazer a configuração. E se você precisar instalar
outras dependências, você faria isso
no componente base. Então, instalando
tudo o
que precisamos e que possamos usar para
instalar outras coisas. Todas essas coisas
vão entrar aqui. Agora vamos ter
nosso segundo estágio do Docker. Aqui. Na verdade, vamos montar nossa imagem final e assumir o
que precisamos a partir daqui. E tudo o que
não vamos assumir será realmente
descartado no final, o que é bom porque isso nos
economiza um pouco de espaço porque não estamos
assumindo coisas desnecessárias. Na verdade, vamos definir essas três variáveis
exatamente da mesma forma aqui. Então, eu vou
apenas copiá-los. Agora, a próxima coisa
que vou fazer é realmente
pegar esse comando do usuário. E vamos
mover isso para cá. Porque quando
estamos copiando em um segundo, eu realmente quero ter
certeza de atribuir esses arquivos especificamente
ao usuário. Mas antes de
fazermos isso, teremos
um comando de cópia aqui porque primeiro
queremos colocar todos os nossos pacotes que
instalamos com nosso PIP n nessa imagem. Agora, vou usar um CH próprio. E aqui vamos
definir o grupo primeiro. Portanto, o grupo aqui é meu aplicativo, e deve ser
igual, não dois pontos. O cólon vai aqui. Então esse será
o grupo e esse será
o usuário. E vamos adicionar
outra bandeira da base. Esse espaço faz referência a esse
pseudônimo que temos aqui em cima. Agora, vamos copiar
o conteúdo do diretório
pirata, da nossa base para nosso diretório pirata
nesta imagem aqui. Então, essencialmente, estamos
copiando agora todas essas coisas que instalamos aqui com a instalação do pip, estamos copiando todos esses pacotes
porque precisamos
deles , porque precisamos deles, porque precisamos aquelas coisas instaladas para executar
nosso aplicativo. E esse comando, essa sintaxe aqui é algo especial que
podemos adicionar ao Docker e aos interesses, significa
copiá-lo e atribuir
os privilégios dessas coisas copiadas
ao nosso usuário. aqui. E é daqui que
queremos copiar. Tudo bem, agora que
copiamos todos os pacotes que
precisamos instalar, vou manter este ano porque vamos
manter nosso diretório. Vou manter nossa atribuição
do diretório de trabalho. E, em vez de simplesmente
copiá-los diretamente, agora
vou copiá-los com privilégios atribuídos
a esse usuário. Assim. Sim, é isso. É isso mesmo. Este é nosso comando
Docker atualizado. E vamos executar isso para
garantir que funcione. E então vamos falar sobre
isso mais uma vez. Então, vou, primeiro, remover a imagem
que executamos anteriormente,
que é sim, esse é o
nome que atribuímos a ela. Então, eu preciso remover
este primeiro. E eu vou realmente
usar isso e novamente aqui. E o que vou fazer é porque isso me ajuda a
executá-lo várias vezes. Se tudo
passar, vou
remover a imagem que
criei anteriormente. Obviamente, isso só funciona se eu tiver executado esses dois comandos primeiro. Mas uma vez que eu executo esse docker run, eu só quero executá-lo com o mesmo nome repetidamente. Vou remover a imagem
existente, desculpe, não a imagem. Vou remover esse contêiner
existente. Vou criar
uma nova imagem a partir do nosso modelo de arquivo
Docker. Atribua a mesma tag. Vou executar essa imagem como um novo contêiner com esse nome. Então, vamos tentar isso. Ok? Então, podemos ver aqui que também temos dois
estágios diferentes acontecendo. Temos um estágio básico e
temos nosso estágio final. E lá vamos nós. Felizmente, nosso sistema ainda
está funcionando. Mas integramos algumas das melhores práticas de impressão
obscura. Agora não estamos funcionando
como usuário root. Em vez disso, estávamos trabalhando como um usuário que criamos
com privilégios reduzidos. E também há uma etapa aqui que, para nós, provavelmente não terá um impacto tão
grande. Mas uma vez que você precise instalar outras coisas binárias para
ajudá-lo a instalar outras bibliotecas, como primeiro, você precisa instalar algumas coisas para
poder instalar outras coisas. Isso o ajudará porque as coisas que você
instalou anteriormente, depois de instalar
sua biblioteca, talvez
você não precise mais delas. Portanto, esse processo só
vai ajudar nisso porque, essencialmente, muitas
das coisas de configuração que
talvez precisemos instalar, mas talvez não precisem após a conclusão da instalação
, podemos descartar tudo isso. Então, tudo aqui
que não estamos copiando
especificamente
neste estágio final aqui. Atualmente, esse é
nosso estágio final. Tudo incluindo isso. Tudo isso aqui que não for copiado aqui
será descartado. Então, isso só vai
nos ajudar novamente a economizar memória. E sim, este é um edifício de
vários estágios com um
adicional em execução como usuário Também
podemos alterar
isso para usar o ID de usuário que
atribuímos a ele aqui. E vamos executar isso novamente para garantir que
isso ainda funcione. Se você procurar modelos do Docker, tanto dentro de uma organização
quanto on-line em algum lugar eles seguirão um formato
semelhante a esse. Eles podem ter algumas
diferenças em algum lugar, mas esse será
o objetivo principal: você ter uma imagem base e, muitas vezes talvez também
veja como uma imagem base. Em seguida, você verá uma imagem do construtor onde o
processo de construção realmente acontece. E então você verá
a imagem final a
qual as coisas são
copiadas. Pode haver até
mais de duas etapas envolvidas, mas é a mesma ideia de fazer a configuração e depois
copiar tudo o que precisamos e
descartar o resto para criar um pouco nossas
imagens finais. menor para não usarmos
memória desnecessária em nossas imagens. Essencialmente, não
queremos coisas instaladas que
não vamos usar é o objetivo
de tudo isso. Tudo bem? Então, sim, há mais uma
otimização que podemos fazer, que na verdade
vou fazer agora. Temos dois estágios aqui. E, geralmente, uma boa meta é
ter o mínimo de
estágios possível. Então, o que vou
fazer é, em vez de ter o ponto principal do lado de fora, na verdade, vou mover isso
para nosso aplicativo aqui. Assim. Copie isso. E em nosso pote principal aqui. Ainda temos nosso
aplicativo definido aqui. E eu não acho que
precisemos realmente
mudar nada
aqui, o que é ótimo. Mas agora, em nosso arquivo Docker, precisamos, agora podemos
essencialmente remover isso. Também podemos remover um
desses aplicativos porque agora tudo estará
contido em nossa pasta de aplicativos aqui. Também podemos remover esse aplicativo
se quisermos. Ou, alternativamente,
poderíamos deixar isso dentro e fazer assim. E vamos criar e executar
isso mais uma vez. E espero ter atualizado
todas as referências corretamente. Vou demorar
um pouco mais porque fizemos algumas
alterações em nosso código aqui. Então, em algum momento antes
da cópia, Oh, ok. Deixe-me descobrir rapidamente
o que está acontecendo aqui. Main.py. Bem, eu acho que isso é
apenas tentar assim. E agora preciso atualizar meu ponto de entrada aqui porque nosso diretório de trabalho
está um nível acima. Então, preciso ter certeza de entrar nessa pasta e
executá-la a partir daí. Sim, mais uma vez. terceira ou terceira vez é um
encanto. Tudo bem, lá vamos nós. Então, com essas etapas,
conseguimos reduzir o número de etapas que temos em nosso
arquivo Docker em uma, o que é bom. E, essencialmente, só tivemos que
alterar alguns
dos arquivos que
criamos em algumas das referências de nome
dela aqui para garantir que tudo esteja
no local certo, que estamos
referenciando-o no lugar certo. Então, agora estamos essencialmente
nesse nível. Aqui, vamos para
nossa pasta de aplicativos, para nossa pasta de aplicativos, estamos referenciando o arquivo principal. E aqui ainda estamos
fazendo referência a esse aplicativo, esse aplicativo inicializado
que criamos aqui. Então, o processo
ainda é o mesmo, mas nós meio que o
colocamos em uma única coisa aqui. Reduzimos
os passos de nossos estados em um, o que é melhor. Quanto menos etapas você
tiver, melhor será. Vamos apenas buscar uma coisa
boa geral. Agora, antes de
encerrarmos esta lição das melhores práticas do
Docker, percebi que
também queremos adicionar nosso usuário igual a um voo
aqui, porque
queremos ter certeza de
que todos os das melhores práticas do
Docker, percebi que
também queremos adicionar
nosso usuário igual a um voo
aqui, porque
queremos ter certeza de
que todos os nas instalações que estamos
fazendo, você realmente estará com
o mesmo nível de usuário, para que não tenhamos algumas coisas instaladas
em nosso sistema e outras coisas
instaladas em nosso usuário. Além disso, também
notei um pequeno erro de digitação,
ou seja, deve ser o usuário
primeiro e depois o grupo. Então, vamos corrigir isso rapidamente também. E lá vamos nós.
5. Docker Compose: Tudo bem, então, anteriormente,
nos
aprofundamos nesse arquivo
Docker e o
reestruturamos de uma forma mais agradável seguindo as
melhores práticas. Agora vamos
dar uma olhada no Docker Compose porque atualmente quando estamos
usando o arquivo Docker, quem está construindo
o arquivo único e depois o executamos. Mas, na verdade, o que será bom e o que você verá
também quando chegarmos a ele mais tarde, quando adicionarmos
bancos de dados e cache, e outras coisas é que não queremos apenas ter
nosso aplicativo em execução, também
queremos ter um execução de banco de dados que podemos
usar com nosso aplicativo. E provavelmente também queremos
ter um cache separado em execução que queremos usar
com nosso aplicativo. E assim, poder configurar todo
esse sistema
que possamos reutilizar. E, na verdade, há muitas coisas
legais que você
pode configurar e, bem, é um tópico profundo para
mergulhar e obviamente, não vamos
cobrir tudo, mas vamos abordar
os pontos principais. E, à medida que abordarmos mais adiante
neste curso, também
tocaremos nesse Docker Compose novamente
e adicionaremos componentes a ele. Por exemplo, o banco de dados no dinheiro que acabei de
mencionar. Mas a questão é que
às vezes simplesmente não queremos executar algo
que seja meio isolado, mas queremos executar
várias coisas
e talvez essas coisas ou até mesmo conectadas. Então, para facilitar esse
processo para nós, vamos usar o
Docker Compose. Então, vamos começar criando um novo arquivo aqui. E eu vou chamar
isso de Docker de composição. Um Docker, Compose
dot YAML, como este. Se você tiver o Docker
instalado, você
também deve ter o Docker Compose. Então, tudo
já deve estar configurado para você. Tudo bem, então vamos escrever um código esqueleto primeiro e depois vamos
explicar o que está acontecendo. E, essencialmente, a
primeira coisa que
vamos tentar fazer é tentar reproduzir o que tivemos
correndo com mais escuro. Mas agora, em vez de
usar o Docker Compose, queremos apenas colocar o
mesmo serviço em funcionamento como um contêiner Docker
que
ainda podemos acessar por meio de
nosso navegador da web. Então, a primeira coisa que
preciso definir aqui é qual versão
usaremos da sintaxe usaremos
aqui na versão três. E então vamos definir
os serviços que
estão sendo executados aqui. Você pode ver que eu tenho o plug-in
Docker instalado. Então, algumas dessas coisas,
na verdade, são preenchidas automaticamente. Se você não o tiver
instalado, ele não o instalará. E se você ainda tiver essa
notificação aqui, obviamente
, a maneira
mais fácil é
clicar em instalar o plug-in e ele o
instalará para você. Mas, novamente, não é realmente necessário. Isso só ajuda, ajuda com o preenchimento automático
e outras coisas. Mas sim, tudo bem, então
aqui vamos
definir os diferentes
serviços que estão sendo executados. Um desses serviços, por exemplo
, será seu aplicativo. Vamos
definir um serviço. Vou dar a ele o nome de app. Podemos chamá-lo do que quisermos, mas vou dar
o nome de aplicativo só para
esclarecer o que é isso. E agora, aqui,
vamos
definir melhor algumas das
coisas sobre isso. Então, a primeira coisa que
eu queria descobrir é como posso criar
esse aplicativo? Qual é o arquivo Docker
que precisamos referenciar? Em alguns casos,
podemos estar referenciando um arquivo Docker que
está no Docker Hub. E em outros casos,
queremos referenciar aqui
um arquivo Docker que temos. Então, vou ter
esse parâmetro de fatura e vou apenas
apontá-lo para o diretório atual. Então, basta usar um
único ponto para isso. Agora, a outra coisa
que eu quero
fazer para ter acesso a ele, que também fizemos anteriormente, é definir
os mapeamentos de portas. Então Docker, usamos
isso menos p Here. Vamos fazer com que
isso seja um porto. E podemos ver aqui que ele
já o preenche automaticamente para mim. Mas, basicamente,
teremos cólon depois daqui. Vamos entrar em uma nova linha. E então teremos
um traço que indica que isso
será uma matriz. Portanto, podemos fazer vários mapeamentos de
portas, pois vamos
usar apenas um mapeamento de porta, aqui será novamente da porta
80 para a porta 80, 80, assim. E aqui podemos ver que estamos
começando isso na porta 80, 80. Portanto, queremos ter certeza de
que nossa porta externa esteja mapeada para a porta de visão
correta. A mesma coisa que
abordamos quando executamos o arquivo
Docker individual. E é isso, na verdade, o que precisamos para
reproduzir essencialmente o que tivemos
com nossa compilação do Docker. Então, vamos em frente
e intensificar isso. Então, a primeira coisa que
precisamos fazer para isso funcione é usar o comando docker dash
composted. E então vamos
digitar aqui em cima. E também vamos adicionar uma bandeira adicional que
será menos menos construção. E isso significa
que vamos girar nosso contêiner, mas também vamos
construí-lo primeiro. Então, primeiro construa do que gaste. Então, vamos seguir em frente e executar isso. Provavelmente vou
levar um
pouco de tempo para construir. A maior parte deve ser armazenada em cache. E vamos ver aqui. Ainda está criando isso.
Tudo bem, então vamos lá. Temos nosso contêiner funcionando. E se eu clicar nisso,
eu deveria ter acesso a ele. Então, se você acessar a página de documentos e tentar um desses pontos finais. Tudo bem, vamos lá, Cool. Então esse é o valor padrão que temos e está funcionando. Então, se quisermos
retirá-lo, bem. Agora não o estamos executando
no modo daemon. Então, se eu pressionar o Controle C, ele realmente vai pará-lo, o que podemos ver se
voltarmos aqui, atualizando-o agora está desativado. Mas se quisermos
executá-lo no modo daemon, como fizemos com nosso Docker. Então, depois de executá-lo
em segundo plano e não ocupar
o primeiro plano aqui, vou fazer a mesma
coisa, menos, menos a construção. E então eu vou
adicionar uma bandeira menos d aqui e executá-la mais uma vez. Novamente, tudo
deve ser armazenado em cache, então deve ser bem rápido. E lá vamos nós. Então, agora ele ainda está sendo executado em segundo plano. Eu posso fazer o docker ps para ver
se isso está realmente funcionando. E se eu for me refrescar, então, novamente, estamos correndo. Agora, se eu quiser desativar
o serviço, posso fazer o Docker Compose Down, o que vai
parar com tudo isso. E, novamente, se eu atualizar isso, vamos
lá. Não está mais correndo. Tudo bem, até agora tudo bem, certo? Muito simples e
muito conveniente. Mas até agora, não há muita diferença em usar
o comando Docker, certo? É um pouco mais curto porque podemos fazer a etapa
de construção e execução ao mesmo tempo aqui, mas ainda não muito mais curta. Então, vamos nos
aprofundar um pouco mais e ver algumas
das outras coisas legais
que podemos fazer. Então, uma das
coisas adicionais que podemos fazer, por exemplo,
é que podemos definir essa variável de ponto de
entrada. E aqui vamos usar
a mesma sintaxe
que tínhamos em nosso comando aqui. Ele vai pegar
isso e copiá-lo. Mas talvez o que eu
realmente queira fazer, vou copiar
isso aqui, é quando estamos construindo nosso arquivo Docker e
queremos executá-lo em algum lugar. Obviamente, não queremos
executá-lo com a bandeira de recarga de
traço, traço,
porque isso
adicionará muita sobrecarga
que não queremos. Mas quando estamos nos
desenvolvendo
localmente, é muito bom ter
essa bandeira porque
podemos mudar coisas e
fazer coisas. Podemos simplesmente desenvolver mais rápido
porque não precisamos
desativá-lo se iniciarmos
nossa aplicação. Então, idealmente, poderíamos usar esse sinalizador de menos, menos recarga. Portanto, se definirmos um ponto de entrada em nosso nível do
Docker Compose, ele realmente
usará esses pontos de entrada ou esse comando em vez de qualquer
comando final que tenhamos aqui. Então, nesse caso, se
eu executar isso novamente, docker-compose up,
eu o construo e o executo. E o modo David,
veremos em um segundo. Na verdade, não vamos. Então, vou
retirá-lo e executá-lo não no
modo daemon, para
que possamos ver a saída diretamente. Vamos fazer isso
mais uma vez. Aqui vemos que iniciamos uma
recarga de nosso processo. Isso porque temos
esse sinalizador de recarga agora ativo. Então, podemos ver que isso
funciona corretamente. Infelizmente, porque estamos executando
em um contêiner Docker. Então, se eu atualizar isso, isso está funcionando conforme o esperado. Mas se eu tentar fazer
alguma alteração, por exemplo, entrar aqui e talvez apenas atualizar o
nome desse ponto final, como adicionar
algo aleatório aqui. Já podemos ver
que ele não está reiniciando. E se eu atualizar aqui, também
não está atualizando. Mas, idealmente, o que eu
gostaria é
poder ter essa coisa em execução e poder
editar meu código. E como estou editando da mesma forma
que fizemos quando o executamos
localmente sem o Docker, quero poder ter esse
tipo de atualização. A maneira como vamos
fazer isso é derrubar isso novamente. Vamos adicionar um componente
extra aqui
, chamado
volume ou volumes. E o que os volumes
nos permitem fazer é que eles nos permitam
mapear essencialmente armazenamentos externos para locais dentro
de nosso contêiner. E os volumes são extremamente
bons porque nos
fornecem um
método persistente de armazenamento. Então nossos contêineres
podem cair, certo? se tivermos nosso Docker em execução
e salvarmos coisas, ideal é que não queiramos
salvar nada em nosso contêiner porque esse
contêiner pode ser desligado. E a maneira como nossos
contêineres
devem
funcionar é que devemos ser
capazes de acionar um novo
e ele deve ter exatamente
o
mesmo estado do anterior. Como se não devesse
evoluir com o tempo. Se quisermos armazenar informações, nós as enviaremos para bancos de dados em algum lugar. Ou, se for um banco de dados em si, ele deve armazená-lo
em algum tipo de armazenamento que, mesmo que o
contêiner caia, o armazenamento ainda esteja disponível. E é isso que esse
volume nos permite fazer. Ele nos permite mapear locais
externos de armazenamento para locais em
nosso contêiner Docker. Podemos usar isso para bancos de dados
que veremos mais tarde para
manter os dados à medida que aumentarmos
e diminuirmos uma instância de banco de dados. Mas, na verdade, vamos
usá-lo por enquanto, se vamos mapear
nossos estados locais do nosso código no estado do código em nosso
Docker Compose. O que vou fazer
é mapear nosso diretório atual para. Este lugar aqui em
nosso arquivo Docker. E isso não deveria estar aqui. Então, vamos analisar
isso mais uma vez, depois vamos executá-lo e
ver como está funcionando. E então talvez
dedique mais alguns minutos para pensar sobre o que
realmente está acontecendo aqui. Mas, essencialmente, o
que fizemos foi em nosso arquivo Docker aqui, criamos um novo aplicativo SRC do usuário de
localização de pastas. E, essencialmente, porque
estamos copiando esse aplicativo para essa
pasta do aplicativo, nesse caminho, esse local em que
estamos nessa pasta, esse diretório
representa essencialmente o que temos aqui. Não copiamos tudo, mas essencialmente, é
isso que temos. Copiamos as
coisas que precisávamos. Então, se eu adicionar o
mapeamento aqui, por exemplo, da nossa localização atual para essa localização
no arquivo Docker. Então, na verdade,
mostrarei isso agora, e adicionarei a bandeira
menos d novamente. Porque agora podemos
executá-lo em segundo plano. Agora vamos mapear
esse local dentro do nosso arquivo Docker para esse local que está atualmente
em nossa máquina local. Vamos ver isso em ação. Então, se eu atualizar isso,
anote isso. Ok, lá vamos nós. Então, agora ainda temos
o que temos aqui. Agora vamos seguir em frente
e fazer uma mudança. Vou adicionar um a
mais aqui, Salvar. Vou atualizar
a documentação. Agora podemos ver que nossas atualizações
foram realmente refletidas. Então, novamente, a
razão pela qual
pudemos fazer isso é porque anteriormente, não conseguíamos
acessar depois de
criarmos nossa imagem do Docker e começarmos com
o contêiner, éramos incapaz de acessar
seu conteúdo internamente. Mas agora criamos um
mapeamento dessa pasta aqui para esta pasta aqui. E o que também
podemos fazer é ser mais específicos e apenas mapear. E eu vou desfazer essas
mudanças aqui assim. E vamos fazer o Docker
Compose Down. Só para que comecemos
do zero. Podemos ser mais específicos e mapear a
pasta do aplicativo que temos aqui para o aplicativo
que temos lá. Então estamos, porque estamos copiando isso
em nosso arquivo Docker, assim,
que estará nesse caminho. Vamos fazer um
mapeamento da pasta do aplicativo aqui para o local que o aplicativo será copiado
sobre um e nosso arquivo Docker. Atualize isso mais uma vez. Lá vamos nós. Então, o que tínhamos, agora vou
atualizar este novamente
aqui, salvar, atualizar. E lá vamos nós. Então, novamente, os volumes nos permitem mapear esses armazenamentos de dentro do nosso contêiner para algum
tipo de armazenamento externo. E isso é muito bom porque dessa
forma, também podemos salvar dados externos. E se um contêiner cair, podemos simplesmente conectá-lo
ao volume persistente. Você não tem acesso exatamente
aos mesmos dados. O que é obviamente
muito bom se tivermos bancos de dados em execução, por exemplo ,
e sim,
lembre-se disso. Isso se você estiver executando
um contêiner Docker e
salvando em um arquivo local. Depois que o contêiner é desativado, esse arquivo desaparece. Portanto, sempre, se precisar de alguma coisa, sempre salve-a em algum lugar fora do contêiner,
pois você
realmente não terá
acesso muito fácil a ela dentro do contêiner e, uma vez
que ela cair, ela desaparecerá. Então, apenas mantendo isso em mente. E é novamente aqui que
os volumes realmente nos ajudam. Ok? Então, os volumes são bonitos, isso é mais ou menos o que
temos agora, que é essencialmente
o aplicativo que tínhamos anteriormente. Deixe-me retirá-lo. Agora podemos fazer
muito mais conosco. Portanto, temos nosso aplicativo
atual. Mas algo que também
queremos fazer é
poder executar nossos testes de
unidade, por exemplo, idealmente, executaríamos isso no contêiner Docker,
porque essa é exatamente a configuração
que estamos fazendo ter quando está
sendo executado em produção. Porque esse é o
objetivo principal disso, que temos essa configuração
reproduzível. Então, vou
criar um novo serviço. Vou chamar
esse aplicativo de menos teste, apenas para indicar que se trata de
uma versão de teste do wrap. Eu vou levar isso aqui. E eu vou
copiar a maior parte disso. E eu não vou
atualizar o ponto de entrada. Isso realmente não
importa muito. E também não preciso de um
mapeamento de portas porque,
na verdade, não quero fazer nada
com nosso contêiner de teste. Além disso, se eu usar
esse mapeamento de portas, teremos um
conflito porque já
mapeamos nossa
porta do sistema para essa porta. E assim, o contêiner Docker, e não podemos remapear
a mesma porta duas vezes. Então, isso realmente
causará problemas. Então, precisamos
remover isso de qualquer maneira. E vou agora, em vez de
mapear o aplicativo,
apenas a pasta do aplicativo, na verdade
vou
mapear todo esse diretório porque se
entrarmos em um arquivo Docker, você notará que
não estamos realmente copiando na pasta de teste, mas ainda precisamos
ter acesso a ela dentro de um contêiner Docker. Agora, quando executarmos isso, na verdade
teremos dois contêineres
separados em execução. O primeiro será
seu aplicativo que estamos usando
atualmente com essa sinalização de recarga de
barra, o
que nos permitirá, porque estamos mapeando nossa pasta
aqui para aquele local dentro do Docker contêiner
para fazer o desenvolvimento e analisá-lo em nosso navegador da web e
poder brincar com ele. Esse contêiner aqui será
essencialmente responsável por apenas
executar testes de unidade para que possamos
realmente testar nosso código. Ok? Tudo bem, então ainda há algumas outras coisas que
precisamos cuidar porque se entrarmos em
nosso arquivo Docker, percebemos
aqui que não instalamos nenhuma dependência de desenvolvedor e precisamos as dependências do desenvolvedor para
poder executar nossos testes unitários. Agora, o que precisamos
fazer é atualizar
nosso arquivo Docker para que o
processo de instalação que acontece aqui seja diferente,
dependendo se estamos em nosso aplicativo ou se estamos em o aplicativo destinado apenas à execução
de testes. Então, vamos fazer isso primeiro. Agora, precisamos de
algum tipo de forma de indicar onde estamos atualmente. Agora, uma ótima coisa que
você normalmente faria com isso é usar variáveis de
ambiente. Infelizmente,
não temos acesso
aos que estão dentro do nosso contêiner
docker, mas podemos fornecer argumentos de
construção. A maneira pela qual podemos
fornecê-los é, em vez de apenas usar
essa sintaxe de construção aqui, podemos realmente
expandir isso. E vou fornecer mais
duas palavras-chave. Então, o contexto será
novamente onde nosso arquivo Docker
ou onde
executaremos essa coisa a
partir do local, que será apenas
o local atual. Então. Agora, aqui também podemos
fornecer argumentos de construção. E, novamente, podemos fornecer isso como uma matriz, enquanto a lista, e nós vamos
fornecer o nome, e então vamos
fornecer o valor. Então, por exemplo, eu posso chamar esse nome de
ambiente, ambiente e ter certeza de que
estou dizendo isso corretamente. Acho que estou. O valor
aqui será um teste. Então, vou
inventar um nome, o que vou
chamar de ambiente. E esse
será o teste de valor. E agora eu preciso
fazer algo
parecido aqui porque não quero ter dependências de desenvolvedores
instaladas em nosso aplicativo. E então este,
eu vou ligar para desenvolvedor ou talvez
eu o chame de local. Então, agora o que eu quero fazer é aprovar esse argumento de projeto de lei. Agora eu preciso
ter acesso
a ele dentro de um contêiner
Docker. E então eu quero atualizar nossa
execução aqui para que, se estivermos, se essa
variável de ambiente aqui for teste, eu também queira instalar
dependências de desenvolvimento. Caso contrário, eu não. Tudo bem, então, primeiro de tudo, para ter acesso a
esse argumento de projeto de lei. Vou usar
essa palavra-chave args. E então eu vou colocar o nome dessa variável aqui. Agora, vou nos dar acesso
a esse argumento dentro da
nossa compilação do docker aqui. Tudo bem, agora o que
precisamos fazer é atualizar essa declaração para condicionalmente e usaremos uma instrução
if para isso, mas usaremos
uma instrução bash IF para instalar
condicionalmente
com dependências do desenvolvedor. Se esse valor de ambiente aqui for, teste para escrever uma
instrução if e um bash. E não vamos
entrar em muitos detalhes aqui, na
verdade, apenas
examinando os ossos básicos para ter o suficiente
para poder fazer isso. Porque na maioria das
vezes você gostaria não precisar de mais do que isso. E se você fizer isso,
porque sabe como escrever
declarações condicionais em Python, entenderá a lógica e poderá transferi-la para o bash. Você só precisa procurar
a sintaxe apropriada. Portanto, a sintaxe será se e depois abrir e
fechar colchetes. E então aqui
vamos colocar IF. E para acessar a
variável de ambiente no Bash, precisaremos colocar o sinal
$1 na frente dela. Então, se o argumento do projeto de lei, se o valor desse argumento de construção ao qual temos acesso, porque o definimos aqui. Se esse valor for igual
ao teste de string. Agora, uma coisa muito importante
aqui é ter espaços antes ou depois e antes de abrirmos e fecharmos
esses colchetes. Então eu vou colocar
um ponto e vírgula aqui. Isso é importante porque,
se quisermos ter mais de um comando
na mesma linha no Bash, precisamos
separá-los por ponto e vírgula. Caso contrário, estaríamos criando novas linhas que
também serviriam a esse propósito. Mas como teríamos a maior parte disso
na mesma linha, vou colocar
um ponto e vírgula aqui. Portanto, se nosso ambiente for de teste, queremos instalar
com dependências de desenvolvimento. Então, queremos fazer
a mesma coisa aqui, mas com dependências de desenvolvimento. Novamente, dois pontos, porque tudo
isso está em uma linha. Agora, porque vamos
passar por cima de uma linha porque eu não quero ter essa
coisa ou como correr para o infinito para o lado
direito. Mas também podemos ver que temos sugestões de
margens semelhantes aqui e não
queremos falar sobre isso. Então, para continuar, algo que estava
na mesma linha. E vamos inserir
uma quebra de linha que podemos fazer com a barra invertida. Vamos continuar com
isso na próxima linha. E então
teremos nossas outras declarações. Outro cólon aqui. E então, para terminar essa afirmação, fazemos FI, então o oposto de f. Então, vamos repassar isso
mais uma vez. O que nós fizemos? Criamos um argumento de construção
que estamos fornecendo à medida construímos nossa imagem
com esse valor aqui. Em seguida, obtemos acesso
ao argumento derramado aqui. E estamos acessando
seu valor aqui. Estamos comparando isso com
o teste de valor usando um
único sinal de igual aqui. Então temos uma declaração
condicional. Então, se esse valor for test, faremos essa instrução de
instalação e
adicionaremos isso menos,
menos dev tall, algumas dependências de
stall dev. Caso contrário,
faremos nossa instalação normal. E então temos algumas palavras-chave
especiais aqui. Só porque é menos assim que
a declaração if se
parece . Isso é o que você
tem que escrever. Tudo bem? Ok, então vamos, bem,
vamos começar com isso. Não, ainda não estamos
executando nossos testes, mas podemos, se quisermos. Então, se
quiséssemos, poderíamos, por exemplo atualizar nosso ponto de entrada aqui
para ser algo como teste e testes de pi. Mas vamos ver uma maneira melhor de
fazer isso em um segundo. Porque se fizermos
assim, só funcionaremos de uma
vez quando iniciarmos. Mas, idealmente, seríamos
capazes de executar à vontade. Tudo bem, então vou executar
a compilação não está no modo David agora para que possamos ver a saída completa. Certo? Então, desta vez, vai
demorar um pouco mais porque atualizamos
nossas declarações aqui. E agora não estamos
mais usando dinheiro,
mas temos que refazer isso, que na verdade inclui
instalar componentes, obtê-los
on-line,
baixá-los durante a
instalação processo. Então, espero que demore um
pouco mais,
não muito mais, porque todo o resto
ainda deve ser armazenado em cache. Espere até que isso
termine. Tudo bem, então nossa construção finalmente terminou. Tudo está começando. Então, podemos ver aqui que este é o
nosso primeiro contêiner em execução, e esse é o nosso segundo. E aqui podemos realmente ver
o resultado dos testes. Temos nove testes que foram aprovados e o outro
contêiner ainda está em execução. Então eu vou fazer um loop, então não quero que cliquei
em um link aqui em algum lugar. Tudo bem, então vamos
anotar isso. Tudo bem, então nós temos isso funcionando. Excelente. Agora, o que
vamos atualizar é em vez de executar
esses testes apenas uma vez. Em vez disso, o que
aprenderemos a fazer é
executar esses testes sempre que
quisermos em seus contêineres. Então, vou construir isso, ativar isso, faturar novamente,
executá-lo e o modo daemon. Se nenhum código foi alterado, você também não
precisa reconstruí-lo, o que obviamente tornará
o processo mais rápido. Então, se fizermos assim
, vamos gerar
a imagem existente que
criamos para ela. Ou melhor, se
adicionarmos a bandeira de construção
, ela será reconstruída. E mesmo
que tudo esteja em cache, obviamente ainda demora
um pouco mais. Agora, para executar nossos testes nesse
contêiner de teste que
temos aqui, vamos usar
docker ps, dash compose. E então vamos
digitar aqui exit exec. Então, vamos executar
algo contra algo. Nosso objetivo será esse serviço de teste de painel de aplicativos
que temos aqui. E o que vamos executar, o comando que vamos
executar,
serão testes de pi test. Então, estamos executando o teste pi
em nossa pasta de testes aqui. Se eu apertar Enter e lá vamos nós. Então, estamos fazendo nossos testes. E agora isso é
muito bom porque tudo está rodando
dentro de um contêiner Docker. Temos vários contêineres
Docker. Temos dois
contêineres separados aqui funcionando. Um deles podemos usar
para o desenvolvimento local. Podemos fazer nossas mudanças. Então, basta ver isso de novo. Se eu remover isso, isso ainda deve estar desaparecendo. E temos esse mapeamento
por causa dos volumes. Temos vários
contêineres funcionando. Um deles é aquele que simula o que teremos
na produção de desenvolvimento, exceto que substituímos
essa bandeira para recarregar. Essa. Embora nunca tenhamos copiado nenhum
dos arquivos de teste aqui, porque não
os queremos em nossa imagem final porque usamos um mapeamento de
volume aqui. Na verdade, ainda temos
acesso a tudo isso aqui. Porque a forma como
essa pasta aparece dentro de uma imagem do Docker agora será
representada pelo que temos aqui localmente. Em seguida, pudemos usar
esse
comando exec do Docker Compose para executar um comando
em um destino específico, que é o nome
que temos aqui. E esse é o comando que vamos
executar contra ele, que significa que sempre que
fizermos alterações, também
podemos simplesmente fazer nossas alterações aqui,
atualizar nossos testes aqui
e, em seguida, quando executarmos Para executá-lo, podemos simplesmente executar
os testes contra ele. E com esse tipo de execução nossos testes de unidade e
tudo fica em um ambiente
Docker muito bom e reproduzível ,
o que é incrível. E com essa configuração, veremos que, no futuro, poderemos fazer muito
mais coisas com ela. Podemos, por exemplo, adicionar variáveis de
ambiente semelhantes. Com apenas um teclado extra aqui, já podemos ver. Podemos preencher essas coisas. Podemos adicionar serviços extras que serão como nossos
bancos de dados e nosso cache, por exemplo, ou se você estiver realmente
criando vários serviços que talvez queiram entrar
em contato uns com os outros, você pode realmente ter
todos desses serviços, serviços
diferentes
que você está criando executando ao mesmo tempo. Assim, você pode testar todos
eles como se
estivessem correndo ao vivo em algum lugar. E isso realmente
nos dá muito poder,
porque somos capazes de simplesmente acelerar tudo, deixá-lo falar um com o outro e ser capazes de testar de
uma maneira muito boa e
reproduzível. Então, sim, Docker Compose. Espero que você ache útil. E, novamente,
há muitos outros
argumentos parecidos aqui que
analisamos ou que nós, que não analisamos que fornecem
funcionalidade extra. E se você precisar de mais
alguma coisa com mais escuro, basta
pesquisar qual é o nome da variável que preciso
fornecer aqui e como
posso colocá-lo? Você poderá definir
isso e o Docker Compose. E, pessoalmente, eu
prefiro isso muito mais porque nossos comandos aqui são muito
mais curtos em comparação
com os comandos mais longos,
como os do Docker. E, novamente, podemos
definir tudo
nesses arquivos de configuração YAML que outra pessoa pode
simplesmente pegar e executar. Caso contrário,
você teria que enviar a eles sua cópia exata de, hum, o que, qual comando
você está executando. Crie seu contêiner
a partir de uma imagem se
quiser fornecer
muitas
variáveis de ambiente ou
algo parecido. Já com esse
Docker compondo YAML, podemos ter tudo
isso pré-configurado. E espero que
outra pessoa seja capaz de
pegar tudo isso,
ativá-lo , executar o
Docker Compose e ser capaz de ter exatamente
a mesma coisa. E isso só torna
tudo mais fácil, tudo mais fácil porque uma vez que você
chega a esse ponto, obviamente é um
pouco trabalhoso chegar aqui. Mas quando você chega a esse ponto, você está em um lugar muito bom. Somos capazes de ter coisas
reproduzíveis. Você sabe, o que você tem aqui é como vai ser quando
você o executa em outro lugar. É muito fácil fazer alterações, adicionar coisas novas e
manter tudo reproduzível e testável
e tudo mais. Então, mais uma coisa rápida que eu quero mostrar é que
às vezes você pode ter, por exemplo, vários arquivos de composição do Docker. E, essencialmente, vamos criar um
novo diretório aqui. Vou
chamá-lo de teste de dívida, DC. Vamos nos certificar de
derrubar meus contêineres existentes. Lá vamos nós. E
então eu vou apenas mover esse arquivo de
composição do Docker para cá. Então, digamos que queremos
ter compositores diferentes para cenários diferentes. Se você precisar de
algo
assim, o que posso fazer é adicionar uma bandeira menos f à
referência, onde está. Se eu executar isso agora,
não vai funcionar porque não consegue encontrar
um arquivo docker compose. Mas se eu adicionar uma bandeira
menos f aqui, posso apontar para o meu
arquivo, que
será intestado, barra Docker, compose, YAML, esse
é o nosso nome de arquivo. E então podemos
tentar executá-lo novamente. E bam, lá vamos nós. Funciona. Então, meio que um
aparte rápido , caso você
se depare com algo assim. Obviamente, para retirá-lo, precisávamos ter a mesma
sintaxe aqui para retirá-lo. E eu provavelmente
não vou querer isso aqui. Assim aqui atrás. Obviamente. Isso não é tão bom quanto tê-lo diretamente aqui e é exatamente
isso que muitos o mantêm. Mas, para deixar de lado, se você se deparar com
algo
assim, é assim que também
podemos fazer isso. Mas sim, então isso é mais escuro. Muitos docker docker compõem. E embora tenhamos feito muito trabalho braçal
para conseguir o que aqui está, agora chegamos a um ponto muito
bom em que, novamente, temos poucos
comandos muito curtos e
legíveis que permitem nós construímos sistemas muito complexos e fazê-los funcionar de uma
forma que seja reproduzível, que é muito bom, porque isso pode
lhe dar muita
tranquilidade para garantir que a
maneira como as coisas estão funcionando aqui vai ser a maneira como
as coisas
estavam funcionando em outros lugares. O que é
muito, muito bom. Sim. Eu sei que algumas
coisas podem ser um
pouco confusas quando você
olha para elas pela primeira vez. Leva algum tempo para
brincar com algumas
dessas coisas. Reserve um tempo para
brincar com esse volume para
entender o que ele faz. Dê uma olhada em cada uma das
coisas que fizemos aqui. Talvez tente adicionar outro arco de
construção ou alterar o nome aqui apenas
para ver o que acontece, para garantir que você se sinta
mais confortável com ele. Mas com o tempo, você se
sentirá mais
confortável com isso. E também, novamente, é porque quando estamos construindo
essas coisas, muitas dessas
coisas acabam
parecendo semelhantes,
por razões óbvias. Portanto, você geralmente
abordará isso da mesma maneira. E, na maioria das vezes,
você terá
modelos parecidos com os quais trabalhar, para ter esses arquivos docker. E então você terá
que adaptar o que está
copiando e como está fazendo a instalação,
etc., etc. Mas muito disso é, na verdade como um modelo padronizado. Você sabe, que você pode reutilizar. E, obviamente, queremos
analisar isso em detalhes,
uma vez que acabamos de ensiná-la entender corretamente
o que está acontecendo , de modo que, se você ler
ou precisar fazer alterações ou acréscimos, você sabe onde procurar,
você sabe o que procurar. Mas sim, na maioria das vezes você terá um
modelo com o qual trabalhar. Você tem um modelo
agora, pode ter um modelo e uma organização
e pode encontrar modelos on-line que podem ajudá-lo a alcançar esse
resultado final muito mais rápido.
6. Makefile: Tudo bem, então
percorremos um longo caminho e realmente
conseguimos chegar a um ponto, o que é muito bom
em não ter que
escrever muita coisa para
colocar as coisas em funcionamento. Mas com o tempo, você
provavelmente, mesmo com isso, ficará frustrado por
ter que escrever repetidamente as mesmas coisas. E há mais maneiras que
podemos usar para encurtar isso. Basicamente, ter atalhos para comandos que estamos
executando regularmente. Agora, isso funcionará
em um Mac e Linux, acho que para o Windows
você precisará fazer alguma configuração extra para que
esses makefiles funcionem, que é o que veremos agora. Mas, de um modo geral, se você acabar trabalhando em uma
organização em algum lugar, é improvável que
esteja trabalhando no Windows? Não sim, não que seja
impossível, é muito mais provável que você esteja trabalhando
em um Mac, Mac ou Linux. Então, sim, apenas
mantendo isso em mente. Vamos falar sobre isso agora
porque é comum criar makefiles para você mesmo ou vê-los
em outro repositório. Porque, como
veremos em um segundo, isso facilitará sua
vida. Novamente, para o Windows, há
algumas outras coisas
que você precisa
instalar para que
esses comandos realmente funcionem. Procurado, é muito importante
fazer isso funcionar. Portanto, esteja ciente disso, que essas coisas existem e é
assim que podemos administrá-las. E você pode criá-los se
quiser ou pode
deixá-los de fora porque
eles são apenas coisas
boas de se fazer. Curto. A sintaxe é ainda mais curta. Mas sim, de qualquer forma. Tudo bem, então vamos criar um novo arquivo aqui
que
chamaremos de arquivo make como esse. E neste makefile, agora
vamos
definir uma série de comandos que nos permitirão essencialmente o que
tínhamos aqui, como o Docker compor traço, traço menos d, só para que não tenhamos que
escrever isso
todas as vezes. Vamos criar um atalho que executará isso para nós. Agora, uma coisa muito
importante aqui é que, se você estiver no PyCharm, como eu estou aqui neste arquivo, queremos ir até o final e clicar nesses
quatro espaços e configurar a resistência
para planície e use o caractere Tab em vez disso. Porque o Makefile tem uma diferença
muito, muito específica entre
quatro espaços e uma aba. Já em outros casos,
como em Python, por exemplo ,
é,
realmente não faz
muita diferença. Então, não há problema em
usá-lo assim. Mas no PyCharm, você
descobrirá que eu fiz aqui, se você estiver usando o Visual Code, se você não estiver usando o código
visual do PyCharm ou qualquer outra coisa, você o encontrará em um local provavelmente
semelhante. Mas, geralmente, se você
tiver problemas,
isso significa que falta
algum separador
ou qualquer outra coisa. Muito provavelmente, o
problema que você está enfrentando é o que queremos. Você esqueceu de colocar um cólon,
o que também acontece. Mas para outros problemas muito
comuns você está usando espaços
em vez de toques. Ok. Eu vou te mostrar também uma
segunda maneira rápida de ver isso. Na verdade, deixe-me desligar
isso por isso, só para mostrar como
seria. Tudo bem, então a
primeira coisa
que queremos fazer é
definir um comando aqui, seja, vou chamar start porque é
curto e eu gosto dele. Mas você pode chamá-lo de qualquer coisa, como correr, girar, qualquer coisa. Vou chamar isso de “start”. Quando executamos esse comando, o que queremos é isso menos a
parte de construção, como essa. Agora, você notará
que estou usando espaços agora,
porque se eu voltar, voltar aqui, você notará
que ele volta quatro vezes. Então, esses são espaços. E se eu mudar isso de quatro espaços para usar um caractere de
tabulação, exclua isso e pressione Tab novamente. Agora, quando estou indo para a
esquerda da direita. Então esse é o personagem principal. Uma diferença muito grande
para usar espaços aqui. Você vai ter problemas
e isso é frustrante. Tudo bem, então temos que começar. Outra coisa que usamos muito comumente é começar com build. Então, vou chamar isso de
start underscore build. E aqui eu vou simplesmente
colocar esse comando assim. Outra coisa que queremos
fazer é derrubá-lo. Então você usa derrubar, mas essa é uma palavra longa,
pare com uma palavra mais fácil. E vamos fazer docker, compor assim. E outra coisa que provavelmente
queremos fazer regularmente é executar nossos testes unitários. Podemos chamar isso de
testes unitários de teste unitário para usar o plural porque
provavelmente estamos executando vários testes. E o comando que
vamos executar aqui será o comando
que vimos anteriormente. Então o Docker Compose x menos t e ele estará apto
a testar, que é contra
esse contêiner aqui. O comando que
estamos executando é pi test, testes como esse. Ok? Então, esses são
quatro comandos que usaremos com bastante regularidade. E aqui, a partir disso,
temos nosso Makefile. Há uma coisa que
queremos acrescentar no topo, que é fornecer
uma lista de crimes. que basicamente
diz ao makefile que esses são comandos. E se alguma vez tivermos
arquivos com esses nomes, quando usarmos isso
com o comando make, que veremos em
um segundo que ele deve tratá-los como comandos. Vamos colocar aqui
todos esses comandos
que queremos usar. Vamos
começar a destacar
a construção. Temos que parar,
temos testes unitários. Tudo bem, então deixe-me ver
se alguma coisa está funcionando. É isso. Então eu vou fazer, bem,
vamos usar nosso comando principal. Então, eu tenho esses dois
ainda funcionando da última vez. O que vou fazer agora é digitar make stop, que executará
esse comando aqui. Quando eu clico em Enter. E podemos ver que ele está executando esse comando e está
derrubando tudo. Podemos começar a executar isso e
isso trará
as coisas de volta para nós. Então veja aqui, se eu atualizar, é Espere 1 s. Lá vamos nós. Tudo bem, vamos
retirá-lo e parar. E lá vamos nós. Agora, se eu me refrescar, vamos lá. Então, não está mais correndo.
Uma coisa a observar: se você não quiser
ver esses comandos, podemos adicionar símbolos at
na frente de tudo. Agora, quando paramos,
ou eu já executo isso? Desculpe, microfone, comece. Agora não vamos ver
o comando imprimi-lo. Então, isso é só um pouco
para conseguir coisas até aqui. Se quisermos executar nossos testes de
unidade, testes de unidade, que serão executados nosso aplicativo de teste aqui, basta executar esse comando
como vimos anteriormente. Bam, lá vamos nós.
Outro comando que talvez queiramos fazer é
verificar nossa digitação. Assim, podemos verificar a digitação. E eu vou executar
esse comando aqui, ou executar em
nosso contêiner de teste. Vou comer
minha torta assim, como fizemos anteriormente. E então podemos verificar
digitando isso para o nosso falso. E diremos que verifique a digitação, que agora
deve comparar a digitação relação ao nosso
contêiner de teste aqui. Enquanto isso estiver em execução, vamos
fazer uma abreviação, porque às vezes talvez queiramos
executar testes de unidade aqui
em nosso contêiner. Mas, em alguns casos, se seus contêineres, o docker compose ficar muito grande
e você não quiser ter todas essas coisas em execução algo
que você possa
fazer talvez algo
que você possa
fazer também seja
executado. coisas localmente. Então, talvez às vezes você simplesmente não queira girar
um contêiner, porque talvez o contêiner
também demore muito. Então, o que podemos fazer em vez disso
é adicionar tipos de aliases para isso
e depois reutilizá-los. Então, por exemplo, vamos criar
um alias para testes de unidade. E isso aqui vai ser, desculpe, deveria haver um igual. Serão
testes de pi como este. E agora, se quisermos nos
referir a testes de teste de pi, podemos nos
referir a esse alias usando o símbolo $1 aqui e depois abrir e fechar
parênteses ao redor dele. E então podemos fazer nossos testes de unidade como
fizemos anteriormente. Assim. Também podemos ter
outro que será um teste
de unidade. Local como esse, que só vai executar
nossos testes unitários. E isso provavelmente
falhará porque eu não estou no meu
ambiente virtual no momento. Mas vamos ver. Sim. Então, vamos em frente e
escolher Penn Shell. E vamos tornar os
testes unitários locais novamente. Vou abrir um
novo terminal aqui, entrei em um estado estranho. Faça testes unitários, locais. Tudo bem, então vamos lá.
Portanto, essa é uma boa maneira de reutilizar isso
e coisas semelhantes, especialmente quando
os comandos ficam mais longos. Sundance também é como você tem comandos que passam
por várias linhas,
que, novamente, podemos separar usando
quebras de linha como essa. Por exemplo, se isso
fosse para uma nova linha, eu poderia separá-la. Mas se tivermos
comandos mais longos e às vezes
também é melhor ter um alias para eles que
possamos referenciar aqui embaixo. Só para que, você sabe,
essas coisas se tornem mais legíveis e não
fiquem tão obstruídas. E sim, isso é mais ou
menos o que estamos fazendo para digitar. E mais, desculpe, não para digitar. Isso é o que podemos fazer
com nossos makefiles aqui, o
que, novamente, apenas adiciona um
pouco mais de simplicidade e torna seus
comandos um pouco mais curtos do que fazer
parar para
derrubar ou contêineres.
do Docker Compose down. Se eu quiser construir,
eu começo a construir. Acabei de encurtar, disse novamente. Só um pouquinho. E sim, esse tipo de
coisa encerra isso. Há mais uma coisa
que eu queria mencionar, não relacionada aos nossos makefiles, que
será apenas analisar os registros. Algo que eu
acho muito fácil de
fazer quando temos
um contêiner Docker em
execução é que, se eu realmente
entrar em nossa área de trabalho do Docker aqui, você pode clicar neles e
ver os registros diretamente aqui. Mas, como um rápido aparte, porque
realmente não fizemos isso, é se você quiser ver os registros e fazer
isso pelo terminal
, existe o comando
docker logs. Então, se fizermos referência a um ID de
contêiner, por exemplo ,
nosso aplicativo principal, e
quisermos ver os registros. Podemos olhar para isso assim. Passo 1: dê uma olhada em
nosso aplicativo de teste e coloque esse
comando aqui. Lá vamos nós. Então, obviamente não
temos
muitos registros no momento. Mas caso você
queira fazer isso e não queira usar o Docker
Desktop para isso
, você também pode fazer isso
pela linha de comando. Já que estamos fazendo muitas
coisas para a linha de comando. E às vezes isso também
pode ser mais fácil para esse processo. Então, sim, espero que você também ache útil ter
esses makefiles. Você provavelmente
os verá também e, sendo usados em qualquer organização à qual
você participará eles terão como makefiles
lá para ter apenas uma lista de comandos que
executam um determinado processo, apenas o torna. É muito fácil ter
apenas makefiles para isso, que seja ainda mais
fácil de executar e você não precise dizer a
outra pessoa qual é o comando. Eles podem simplesmente executar
o comando make e são muito simples de escrever. E, novamente, uma
maneira muito boa de obter essas coisas
reproduzíveis. E, obviamente, eles tornam nossa vida muito melhor porque temos que
escrever ainda menos.