Salve, 10, beleza? Continuamos a nossa saga aqui, nosso módulo de Docker. Agora que nós já sabemos montar uma imagem em Docker, nós montamos ali com um exemplo básico, as nossas necessidades, dependência para produção e desenvolvimento, vão ser mais específicas, mais avançadas, mais complexas. A gente vai requerer colocar um monte de coisas, um monte de configurações ali na imagem, para já subir o container com o que a gente quer. Então, nós temos o seguinte desafio aqui na aula. Nós vamos pegar uma aplicação Node.js, levantar um servidor web com ela, mas normalmente a gente não expõe essa aplicação diretamente, a gente vai colocar o Nginx na frente, porque aí o Nginx vai se comportar ali como o proxy reverso, que aí a gente consegue colocar certas restrições, o Node não ser exposto diretamente também é uma boa prática, eu consigo colocar HTTPS, enfim. Então, bora lá, pessoal. Tudo que eu passar está aqui nessa pastinha, inclusive tem um readme aqui com tudo que eu vou falar nessa aula. Nós temos aqui uma aplicação Node, eu não quero que isso aqui fique falando nada específico de JavaScript. O que eu passar aqui vai servir também para outras linguagens de programação. O que eu estou preocupado aqui são os fundamentos de Docker. Então, aqui eu tenho uma aplicação Node que vai usar o Express.js tão famoso e vai expor um servidor na porta 3000 e vai retornar um Hello World. Muito simples. O arquivo package.json, porque a gente precisa saber quais são as dependências, aliás, libs, para poder rodar a nossa aplicação Node. E o arquivo do Indynex, porque como ele vai se comportar com o proxy reverso, eu preciso fazer uma configuração para falar, toda vez que acessar o barra, você vai repassar as requisições para o localhost na porta 3000, que é o que a gente vai estar rodando aqui com o próprio Node. Então, a gente vai criar aqui a nossa imagem com o Dockerfile. A primeira questão que a gente tem que decidir, inclusive eu posso colocar comentários no Dockerfile com hashtag, é se a gente vai começar a nossa imagem baseada no Nginx ou se ela vai ser baseada no Node. Eu poderia até encontrar alguma imagem de terceiros que já tem os dois e já utilizar para o meu propósito aqui, mas a gente está criando do zero. Então, eu tenho que me basear em alguns dois jeitos aqui. Eu vou escolher a segunda opção, mas você pode fazer com a primeira também. Inclusive, pode ser até um exercício adicional da aula. Então, de um jeito aqui eu vou escolher a segunda opção mas você pode fazer com a primeira também inclusive pode ser até um exercício adicional da aula então vou escolher aqui uma imagem 20 no de limão deve a imagenzinha muito pequena então se vem aqui o node e eu vou ter que instalar o index e como essa imagem um deve eu posso fazer um apt install. Para poder fazer, executar comandos no processo de montar a imagem, a gente usa a instrução run. Então, eu faço um apt install Nginx. Então, a gente vai fazer aqui um docker build. Eu vou chamar essa imagem de Argentina Luiz, vai ter gente que quer subir depois, ou melhor, mynode, depois eu posso gerar uma imagem se eu quiser subir. Vou chamar só de mynode e vamos fazer aqui a compilação. Então aqui a gente já teve o primeiro problema, porque ele não conseguiu encontrar o Nginx. Essa imagem não vem atualizada com aqueles repositórios das ferramentas do apt aqui. Então, a gente tem que rodar um apt update antes. Então, eu posso fazer vários runs. Apt update antes. Então, a gente roda de novo a nossa imagem. Está vendo que ele está batendo lá no Debian aí agora ele já mostrou um outro erro aqui que foi aquela pergunta que ele está esperando a gente colocar um yes para poder fazer a instalação então isso aqui é comum porque é o comportamento normal mas aqui a gente quer que seja instalado direto e aí a gente vai colocar o "-y". Agora vamos rodar de novo. Agora sim ele está instalando o Indynex. Então a gente já vai ter o Indynex instalado dentro dessa imagem. Veja que a etapa anterior ele não executa novamente porque não teve modificação naquela camada. A gente vai entender isso mais tarde. Se eu executar novamente o comando, a gente vai entender isso mais tarde. Se eu executar novamente o comando, também agora o do Nginx vai estar cacheado, a gente não faz a instalação dele novamente. Então, eu posso ter quantos runs eu quiser, em qualquer momento aqui do meu Dockerfile, mas normalmente o que a gente acaba fazendo é colocar os dois comandos no mesmo run, que eles têm relação aqui, e a nossa imagem, quando você consegue agrupar os comandos, fica menor. Então, aqui agora, o passo 2, ele vai ser executado todo novamente. Ele vai fazer o apt update e vai fazer o install do Nginx. Se a gente executar novamente, aí ele vai estar cacheado. Beleza. Então, estamos aqui com o Nginx instalado. Eu tenho que passar esse arquivo de configuração do Nginx para ele entender que ele vai se comportar com o próprio reverso. Então, a próxima linha que eu vou colocar vai ser um copy. A gente já viu como o copy funciona. Eu passo um arquivo que eu quero copiar e para onde eu quero copiar. No caso do Nginx, eu tenho que saber onde que tem alguns locais. O principal local nessa versão aqui que a gente está instalando é o etc.nginx.conf. Então, a gente está copiando o arquivo para cima do arquivo que já vai estar lá. Então ele já vai se comportar dessa forma. Beleza. Agora eu preciso copiar a minha aplicação Node que é o index.js e o package.json Então eu faço um copy index.js mais o package.json. E agora, o problema é para onde? Porque a gente vai ter aquela userland dentro da imagem, mas aonde que eu vou colocar isso? Poderia colocar em barra usr, que é um caminho muito comum., que é um caminho muito comum? Esse app é um caminho muito comum. Vou colocar aqui. Inclusive, esse app não existe lá dentro da userland. Quando a gente tem uma aplicação, normalmente é bom a gente colocar um diretório de trabalho para deixar claro onde que a gente vai trabalhar, onde que essa aplicação vai trabalhar. Então, é como se a gente tivesse um CWB, delimitar-se ali o diretório. Então, como eu vou colocar nesse diretório, eu posso colocar barra USR, SRC, barra app. Então, aqui, eu posso colocar só ponto barra. Olha que legal. Tudo que eu fizer aqui de run e de copy daqui para baixo, vai ser agora diretamente nessa pasta. Eu posso definir o workdir, a diretória de trabalho, aonde que eu quiser. Beleza. Então, se eu tenho isso aqui, eu tenho que fazer a geração da minha NodeMod, porque a minha NodeMod vai ficar aqui, NodeMod lá com todos os arquivos. Então, aqui NodeMods, que a minha NodeMods vai ficar aqui, NodeMods lá com todos os arquivos. Então aqui a gente tem que fazer um npm install. Esse npm install vai ser executado dentro dessa pasta, vai gerar a nossa NodeMods. O NGINX eu não vou rodar ainda aqui? Falta só um comandinho para a gente poder rodar essa nossa aplicação. Que vai ser o comando que vai ser executado no container. Então, a gente vai usar aqui o cmd. O cmd é a instrução que vai informar o Docker qual é o comando inicial. Quando o container iniciar, ele vai executar esse comando. container iniciar ele vai executar esse comando então aqui a gente quer executar o node em usr aqui a gente tem que passar o caminho completo barra usr barra service barra app index.js que é o arquivo que a gente copiou ali então isso aqui vai manter o container de pé também. Se eu executar somente, vamos só fazer aqui o build com o que tem, o npm install vai ser executado agora. Se eu executar de novo, ele está cacheado. Se eu fizer um docker run aqui, vamos colocar aqui o node1, porta não vou colocar por enquanto, myNode, que é a imagem. Mas eu estava morrendo, tem um comando que segurou o meu container. Então, agora eu fiz a mudança ali, eu tenho que fazer o build novamente. Então, agora vamos executar aqui o run. E a gente tem até o resultado. A gente tem até o resultado. A gente tem até o resultado do que está aqui. Se eu tentar fazer um barra C, eu não vou conseguir. Eu vou ter que abrir um novo terminal aqui e fazer um stop do mynode1. do MyNode1. Algumas imagens, a gente não tem ali a conexão com todos os recursos no terminal, aí o Ctrl-C não funciona, mas a gente pode passar aqui uma outra instrução, que é o "-init", tá? Agora o Ctrl-C vai funcionar. Então, o init é que habilita os recursos de conexão com o terminal e a gente consegue fazer essa execução. Então, se eu fizer aqui um "-p 8080 na porta 3000 que está rodando lá dentro do container", vamos ver. Vou fazer aqui um curr. Ó, e o hello world já foi, hein? Então, já consegui. Então, a minha primeira etapa já tá feita. E a gente vê aqui no build, né, que nós temos seis layers. Guarde essa informação, porque nós temos seis comandos. Um, dois, três, quatro, cinco, seis. É, tipo, esse aqui não é considerado, essa última etapa não é considerada. Isso aqui que é a consideração das nossas camadas. Apenas se tiver se eu modificar algo que está em cima, tudo embaixo é executado novamente. Se eu executar algo, se eu mudar somente essa linha aqui, tirar essa linha e acrescentar uma nova, todas as que estão acima são cacheadas. Pronto. Então, aqui restou a questão do Nginx, porque eu tenho que rodar com o Nginx para ele estar como o servidor aqui para a gente. E no Linux normal, a gente executaria o Node, passando ali o caminho para o index, e com um i só, passando aqui o comando do Nginx. Porque se eu passar com dois i, ele vai esperar esse primeiro comando terminar, que ele nunca vai terminar, porque ele vai rodar um servidor. Então, eu não consigo passar isso aqui nesse cmd dessa forma. A gente vai ter que mudar um pouquinho. Eu vou colocar assim, barra bin, barra sh. Inclusive, até não comentei, mas esse command, normalmente ele é definido com essa anotação de array, mas eu posso passar o comando diretamente como uma string. Mas como um array, a gente tem uma melhor interpretação do docker. Então, a gente separa tudo. Ao menos C, que a gente vai executar aqui o nosso comando, aí sim eu posso colocar o I aqui, porque isso aqui vai ser uma parte do comando só. Então, primeiro eu vou executar o node barra usr barra source barra app, e depois barra app index.js, né? index.js e aqui eu executo o index. Ele colocou ali o demon off, que é o normal dele. Beleza. Então, vamos executar aqui o build. De bola. E agora vamos executar o nosso comando. Agora lembrar que o que a gente quer expor, a porta 3000 nós não vamos expor, ela vai ficar lá dentro da inSpace, do container apenas internamente. A gente quer expor apenas 80. Pronto. Ele vai mostrar aqui o log, bonitinho. Mas agora a gente vai ver se a gente vai acessar 8000 a gente colocou 8080 se ele vai retornar o resultado e tem alguma coisa aqui, ah, eu coloquei dois is aqui tá vendo aqui eu rodei com init se ele não parar a gente faz o stop do node1. Por isso que é bom não rodar com "-d", nesses casos, até a gente ter certeza que está tudo ok. Fiz aqui o build. Vamos rodar. aqui o build. Vamos rodar. Ele tem... Ah, eu tenho que colocar um event aqui na... Vou colocar qualquer coisa. Esse worker connections aqui são as conexões que vão ser habilitadas. Vamos rodar novamente. Aí está vendo como eu fiz a modificação agora? Quando ele vê aqui o copy, esse copy daqui ele vê que tem diferença. Então daqui para baixo ele vai executar de novo, mas foi bem rápido. Então vamos executar novamente. executar de novo, mas foi bem rápido. Então, vamos executar novamente. Agora, aí, está aí. Então, a gente está executando, apesar de ele ter mostrado que a porta 3000, a 3000 não está exposta, somente o Nginx na porta 80 está se comportando como um proxy reverso. Então, olha só quantas etapas a gente teve que fazer. Às vezes, a gente faz um copy, depois faz um run, mas essas instruções aqui são as principais. O from a gente já aprendeu, o run executa comandos, o copy copia qualquer tipo de arquivo para qualquer lugar dentro da imagem, a work delimita o diretório de trabalho e facilita a gente colocar coisas em um determinado local. E o cmd para poder iniciar nosso container. Se eu fizer um exec-it mynode1, o node tem bash, então vamos acessar com bash. em Bash, então vamos acessar com Bash. Veja que o diretório que ele já colocou ali para poder trabalhar é o WorkDir. Então se você coloca aqui, quando você acessa sempre o container, ele já vai direto para lá, mas você pode às vezes ir acessar diretamente numa pasta, mas o WorkDir faz isso. Com o ls, olha só o que eu tenho. O index copiado, o core que diria faz isso. Com o ls, olha só o que eu tenho. O index copiado, o lock que foi gerado lá com o npm install no process, ele está dentro da imagem, e a node mods. Vai ter um trocento das coisas. Veja que na minha máquina, eu não precisei de nada para poder rodar isso. Eu fiz justamente porque a gente acaba sendo compelido. Ah, fica fazendo o npm install aqui e depois... Se você fizer o npm install local e copiar, quando acontecer... Apesar que dá para fazer o npm install só para testar, apesar que a gente não colocou o copy.ponto, que é uma outra estratégia que a gente tem aqui. Mas se tivesse um copy.ponto, aí ele copiaria no de mod, depois a gente vai falar mais sobre essas questões também. Então, usamos aqui as instruções principais, vamos avançando aqui no custo, é isso aí, e até a próxima.