Salve, Deus, beleza? Continuando essa saga aqui no nosso módulo de Docker, agora vamos brincar pela primeira vez com o Docker Compose. A gente vai ter aqui um cenário que eu tenho a aplicação Node e outra aplicação que é uma SQL. Elas vão rodar em containers separados. Numa situação sem o Docker Compose, a gente teria que subir uma aplicação, subir a outra, fazê-la se comunicar, e ter aquele cenário de que eu tenho que subir uma aplicação, subir a outra, fazê-la se comunicar. E aí tem aquele cenário de que eu tenho que parar uma, parar a outra, ficar levantando tudo manualmente, são vários comandos. A gente já viu ali ficar fazendo Docker Build, Docker Run, etc. Então, o Docker Compose vai nos ajudar com toda essa gerência. Vamos aqui para o VS Code. Então, a gente vai fazer essa aplicação Node-Scomunicar com uma SQL. Eu tenho aqui um Dockerfile, que é o mesmo Dockerfile que a gente estava usando lá no exemplo de Node mais Nginx, mas eu tirei o Nginx fora para ter somente o Node. Então, a gente vai copiar o index.js e o package.json para a barra usr-source-app. Vai fazer o npm install. Vai rodar um servidor na porta 3000, então é uma expose apenas para poder dizer isso aqui não é necessário, a gente já falou sobre isso, e ele levanta o servidor. Então, aqui no meu index, eu não quero que isso aqui se torne nenhum curso de JavaScript, apenas um exemplo de 24 linhas, que vai usar aqui uma lib MySQL para poder fazer a conexão, depois a gente vai falar aqui das credenciais e aí nós vamos ter aqui um connect, inclusive tinha um connect solto ali se ele não conseguir se comunicar com o banco, vai lançar um erro e vai levantar o servidor na porta 3000. Não tem nem Express aqui, então é somente o MySQL. O package.json define ali a versão da lib que a gente precisa. Beleza. Então, para poder levantar esse conteúdo do MySQL, nós vamos usar o manifesto, que é o Docker Compose YAML. Aqui você pode colocar YAML sem o A ou com o A. Tanto faz. Mas é importante que o nome a princípio seja Docker-Compose, porque quando a gente rodar o comando, como o Dockerfile, lembra que o build, eu coloco o ponto, ele pesquisa o Dockerfile na raiz, vai acontecer a mesma coisa com o Docker Compose aqui. Então, com o YAML que a gente descreve como que esses containers vão se comportar, a qual imagem, a qual Dockerfile ele pertence ali. Então, é um manifesto, a gente declara tudo o que a gente precisa. A primeira coisa que eu vou colocar vai ser a versão. A versão, cuidado para não confundir com a versão do CLI, porque a gente tem duas coisas. Uma coisa é a versão do CLI do Docker Compose, que a gente está na versão 2, e a versão do manifesto. A versão do manifesto não é obrigatória, mas ela acaba fazendo com que quando o Docker Compose pega essas informações aqui para poder montar os containers, as tags, que são essas informações que a gente vai colocando aqui, ele valida, opa, espera aí, você está usando aí um XPTO, mas esse XPTO não é compatível com a versão 3, então acaba sendo conveniente. Há em Services que nós vamos colocar todos os containers que vão ser executados. Então, a gente coloca o nome aqui do container e as instruções de como esse container vai ser executado. Então, vamos colocar aqui o Node. Eu normalmente gosto de colocar nas minhas aplicações, que é o app que eu estou executando ali. Então, aqui eu quero que ele faça o build da imagem para poder criar o container através desse Dockerfile. Então, a gente vai colocar aqui build, dois pontos, ponto. Então, isso significa que ele vai procurar o Dockerfile nessa pasta que eu estou, exatamente. E eu não tenho mais nada para poder definir aqui, a não ser a porta. Muitas dessas informações que são definidas aqui são coisas que a gente aprend exatamente e eu não tenho mais nada para poder definir que não se aporta muitas informações que são definidas aqui são coisas que a gente aprendeu aqui durante o curso da porta eu quero liberar uma 8080 para 3 mil lá dentro do container então quando eu sou só entrando na minha máquina vai acessar a 3.000. Então, essa informação aqui, esse ports, ele é um array, uma tag array, posso publicar várias portas colocando aqui o traço. Deixa eu até comentar sobre o build. Esse aqui é o uso mais básico do build, mas vamos supor que seu Dockerfile esteja em uma outra pasta, você consegue passar aqui outras informações nele também. A princípio, para o Node é somente isso. Agora vamos para uma SQL. Então, vou colocar DB, de Database. Então, aqui eu vou usar um build, porque eu não tenho Dockerfile, eu quero pegar a imagem direta, então a gente coloca a tag image. Então, vai ser uma imagem MySQL, versão 8030-debian, que é a versão que eu já tenho aqui para não precisar baixar. A gente já viu que para o caso do MySQL é necessário definir uma variável de ambiente com a senha do root, porque senão ele não consegue criar o banco de dados quando ele inicia a primeira vez. Então, vamos fazer aqui um environment. Também ela é igual ao port, que ele é um array. Então a gente vai colocar aqui mysql root password igual a root. Se eu precisar colocar outras variáveis de ambiente, só colocar a vírgula e pronto. Uma outra anotação nesse caso aqui que eu poderia utilizar é essa aqui. Tem algumas pessoas que gostam assim, inclusive até um syntax highlight diferente, mas eu prefiro utilizar dessa forma. Aí vai questão de gosto, isso aí não vai ter influência nenhuma. Então pronto, isso aqui é o mínimo. Agora vamos rodar esses containers. A gente tem então o docker-compose-up, que ele vai equivaler ali ao... Na verdade, eu não posso falar que ele equivale ao docker-run. Ele vai fazer duas coisas. Na verdade, ele é igual a um docker-build em tudo que tiver ali, mais um docker-run. Então, ele já faz as duas coisas ao mesmo tempo. Ele vai compilar todos os... Se tiver que fazer o build das imagens, ele faz e depois ele levanta. Então, bora fazer aqui o nosso teste. Aí ele vai retornar uma série de informações. Vamos ver o que aconteceu. Ele está criando o network, depois a gente vai aprender sobre isso aqui. E aí ele pega o nome da pasta para poder servir como o nome do container mesmo, adicionando... Isso aqui é um padrão. Pega o nome da pasta, o nome do service, e esse número é incremental. A gente pode ver aqui que ele começou a iniciar o banco de dados, iniciou o app, aí ele deu um erro de conexão, um connection refused, então ele não conseguiu nem encontrar uma SQL, e depois ele acabou morrendo. Inclusive a gente pode executar aqui o comando docker ps, né? Olha só, eu só tenho o container do MySQL rodando, que ele está com o status, porque o ps só pega o uso rodando, e aqui está o nome do container. O que aconteceu aqui? E aí a gente já começa agora a ter um cenário um pouco mais complexo, porque esses dois containers vão iniciar, e o banco de dados está iniciando pela primeira vez, ele demora alguns segundos para poder consolidar ali, levantar o banco, estar disponível para as conexões, e o Node inicia mais rápido. Inclusive, aqui no histórico, a gente até consegue ver que ele vai reaproveitar layers que a gente já tinha aqui. Eu acho que ele até não mostrou. A gente até poderia excluir imagens relacionadas. Ele iria reaproveitar layers. Então, o Node inicia antes. E aí, o que a gente pode fazer? Tem algumas alternativas, mas a gente vai colocar aqui uma instrução, que é o restart. Olha que legal isso. O restart define como que esse container vai ser iniciado quando ele falhar. Eu consigo também colocar aqui que sempre quando eu ligar minha máquina, ele vai iniciar. Mas se eu colocar aqui um always, então quando ele falhar, que ele terminou, o processo que ia manter ele de pé, crashou, ele vai tentar reiniciar esse container indefinidamente, infinitamente. Então, vamos fazer aqui o seguinte. Eu não preciso fazer nenhum build nem nada, é só fazer um up. Aí, está vendo que ele está mudando as cores? São os reinícios do container. Agora, se nós tivermos outro resultado. Ele falou aqui que o client não suporta o protocolo de autenticação lá com o MySQL porque a gente está usando o MySQL 8. Então a gente vai fazer aqui uma mudança no MySQL. O comando de inicialização dele, nós vamos colocar aqui que é para usar o password nativo e não o outro protocolo que foi inserido no MySQL 8. Lembra do que eu falei sobre o command entry point? Porque quando esse command aqui, ele acaba substituindo o command da imagem. Mas no caso do MySQL, vai ter um entry point lá que força sempre o executável do MySQL. Então é só a gente passar isso aqui e ele vai ser agregado como opção para o comando. Então isso aqui é uma segurança para ninguém desvirtuar a execução do MySQL. Pronto. Então vamos fazer o seguinte agora. Vamos parar aqui e vamos levantar de novo. aqui e vamos levantar de novo. Aí ele vai continuar dando erro porque o banco de dados já foi criado com esse outro protocolo aí de comunicação, então a gente vai fazer o seguinte. Eu tenho que matar o container do... destruir o container do MySQL lá com todo o banco de dados, a gente faz o DAO, então ele destrói tudo já, então tá vendo como que é fácil? E eu faço o up novamente. Mas que ele ainda tá subindo. Pelo menos eu acho que tá. Agora sim que ele terminou. Não, ainda não. Agora sim terminou. O node vai subir novamente. Vamos aguardar. Conectado com o banco de dados. Demorou, ele reiniciou aqui uma. A gente pode pegar pelas cores. Duas, três, quatro. Foram pelo menos quatro vezes aqui de reinício. Olha como ficou mais fácil. A gente já definiu que é uma estratégia que, inclusive, muita gente não conhece. Depois nós vamos falar mais sobre a dependência dos containers, a ordem de como levantar esses caras. Mas a gente administra tudo pelo comando docker-compose. A gente administra tudo pelo comando docker-compose. Acho que todas as instruções aqui ficaram bem claras com relação ao que a gente precisa fazer. A gente vai brincar ainda bastante, não só nesse capítulo, mas em outros também. Esse capítulo aqui serve para poder introduzir, mas os outros a gente vai acabar voltando com o docker-compose também. Então, imagina só, você só rodar um comando, levantar tudo, está tudo descrito aqui, e acaba que essas informações têm incidência no que tem ali na imagem. O command aqui é um caso, porque ele substitui o que a gente tem lá dentro do MySQL. Eu quero deixar claro também em relação ao build e o image que normalmente a gente tende a utilizar um ou outro conforme a nossa necessidade, mas eu posso às vezes ter aqui um build e um image ao mesmo tempo. Isso aqui representa mais necessidade de produção do ambiente ali que eu queira, não estou testando as minhas aplicações em desenvolvimento, porque aí ele vai usar as duas estratégias aqui, quando eu peço para ele poder fazer o build, ele faz o build local, ele não pega a imagem, mas aí ele pega a imagem primeiro, mas eu posso sempre ter ali o Dockerfile para poder fazer o build novamente. Então, já saiba que tem outras várias estratégias, outras combinações que podem ser feitas. Então, pessoal, vamos seguir na nossa saga. É isso aí e até a próxima.