Como Dockerize seus aplicativos para Python | Max S | Skillshare

Velocidade de reprodução


  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Como Dockerize seus aplicativos para Python

teacher avatar Max S, Power through programming

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Assista a este curso e milhares de outros

Tenha acesso ilimitado a todos os cursos
Oferecidos por líderes do setor e profissionais do mercado
Os temas incluem ilustração, design, fotografia e muito mais

Aulas neste curso

6 aulas (1 h 54 min)
    • 1. Introdução ao curso

      1:34
    • 2. Docker Introdução

      9:28
    • 3. Como criar um arquivo do Docker

      35:45
    • 4. Construção em vários estágios

      21:46
    • 5. Docker Compose

      32:40
    • 6. Makefile

      12:21
  • --
  • Nível iniciante
  • Nível intermediário
  • Nível avançado
  • Todos os níveis

Gerado pela comunidade

O nível é determinado pela opinião da maioria dos estudantes que avaliaram este curso. Mostramos a recomendação do professor até que sejam coletadas as respostas de pelo menos 5 estudantes.

51

Estudantes

--

Sobre este curso

Neste curso, você vai aprender como usar seu código Python existente e iniciar como um contêiner docker, tanto usando docker como compose.

A Docker é uma tecnologia muito comum e importante para usar na sua carreira de engenharia de software. Ele ajuda você a criar imagens de seus aplicativos que tenham um estado reproduzível, o que significa que você pode sentir confiança de que, se forem executadas na sua máquina, elas serão executadas em outras pessoas, bem como na nuvem.

Além disso, também facilita o uso de software existente, pois você pode facilmente criar um banco de dados do Postgres ou um cache da Redis sem nenhum trabalho extra, usando essa imagem do docker.

Isso simplifica todo o desenvolvimento, pois você pode reproduzir a configuração de produção em seu ambiente local, o que significa que você pode desenvolver e testar sua aplicação muito melhor.

Você pode seguir com o código no GitHub aqui: https://github.com/codingwithmax/PythonTutorialFastAPI/tree/58CreatingADockerfile

Conheça seu professor

Teacher Profile Image

Max S

Power through programming

Professor

Nota do curso

As expectativas foram atingidas?
    Superou!
  • 0%
  • Sim
  • 0%
  • Um pouco
  • 0%
  • Não
  • 0%

Por que fazer parte da Skillshare?

Faça cursos premiados Skillshare Original

Cada curso possui cursos curtas e projetos práticos

Sua assinatura apoia os professores da Skillshare

Aprenda em qualquer lugar

Faça cursos em qualquer lugar com o aplicativo da Skillshare. Assista no avião, no metrô ou em qualquer lugar que funcione melhor para você, por streaming ou download.

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.