diff --git a/source/pages/guides/docker-fundamentals.md b/source/pages/guides/docker-fundamentals.md index 6527fc46a22060de02da88a91264a84742a9a087..c55873adf7b0e89473f88053b787d7ffb3d8c4c2 100644 --- a/source/pages/guides/docker-fundamentals.md +++ b/source/pages/guides/docker-fundamentals.md @@ -7,6 +7,7 @@ Antes de começar a executar comandos é preciso ter Docker instalado no sistema Há documentação oficial[^cite_docker_install] sobre instalação. ## Trabalhando com **contêineres** +TODO: rootless-docker e sobre como ele é executado ### Utilizando imagens pré-construídas Vamos iniciar com prática: pegar uma imagem que já foi construída por alguém e executar um contêiner baseado nela. Para este guia foi escolhida a imagem do @@ -158,6 +159,27 @@ root@devops:~# Note que tanto o identificador do nome quando do id do contêiner servem. +:::{tip} +Além de que tanto faz se o comando recebe o ID ou o NOME do contêiner, se o +comando receber apenas o prefixo do identificador, supondo que esse prefixo não +se repete o efeito é o mesmo. + +Veja um exemplo em que se faz isso utilizando o ID: + +``` +root@devops:~/node-test# docker ps -a +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +80d9d7b2dab1 node "docker-entrypoint.s…" 2 seconds ago Exited (0) 2 seconds ago awesome_roentgen +ec38d6715864 node "docker-entrypoint.s…" 32 seconds ago Exited (0) 32 seconds ago jolly_gates +root@devops:~/node-test# docker rm 8 +8 +root@devops:~/node-test# docker ps -a +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +ec38d6715864 node "docker-entrypoint.s…" 41 seconds ago Exited (0) 40 seconds ago jolly_gates +root@devops:~/node-test# +``` +::: + #### Removendo contêineres automaticamente Para remover automaticamente um contêiner que você executou é só passar a flag `--rm` para o comando `docker run`. @@ -281,12 +303,70 @@ Além do código, o seguinte texto deve estar em outro arquivo chamado Pronto! Já podemos iniciar essa seção. +##### Executando o programa localmente +Caso exista algum interesse em executar a aplicação localmente para comparar +com a execução 'dockarizada' basta primeiro instalar o Node na máquina em que +se quer fazer o teste. Após isso, no diretório com ambos os arquivos criados +basta executar: + +``` +npm install +npm start +``` + +Após isso, em outro terminal se você executar a seguinte sequência de comandos +o output deve ser o mesmo: + +``` +root@devops:~/node-test# curl -w "\n" localhost:3000/ler +{"texto":"O arquivo nao foi modificado!","contador":0} +root@devops:~/node-test# curl -w "\n" localhost:3000/escrever +{"texto":"O contador eh 1","contador":1} +root@devops:~/node-test# curl -w "\n" localhost:3000/ler +{"texto":"O contador eh 1","contador":1} +root@devops:~/node-test# curl -w "\n" localhost:3000/escrever +{"texto":"O contador eh 2","contador":2} +root@devops:~/node-test# curl -w "\n" localhost:3000/escrever +{"texto":"O contador eh 3","contador":3} +root@devops:~/node-test# curl -w "\n" localhost:3000/escrever +{"texto":"O contador eh 4","contador":4} +root@devops:~/node-test# curl -w "\n" localhost:3000/ler +{"texto":"O contador eh 4","contador":4} +root@devops:~/node-test# +``` + +O terminal acima é o que chamamos de 'cliente'. + +Voltando ao primeiro terminal, o output deve ser similar a esse: + +``` +root@devops:~/node-test# npm start + +> docker-tutorial@1.0.0 start +> node app.js + +Escutando na porta 3000 +[LEITURA] contador eh 0 +[ESCRITA] contador foi de 0 para 1 +[LEITURA] contador eh 1 +[ESCRITA] contador foi de 1 para 2 +[ESCRITA] contador foi de 2 para 3 +[ESCRITA] contador foi de 3 para 4 +[LEITURA] contador eh 4 +``` + +Esse é o terminal que chamamos de 'servidor'. + +Agora vamos ver como fazer isso executar com Docker. + #### Criando um Dockerfile Quem já conhece Node sabe que para executar o código será preciso primeiro instalar as dependências do projeto com `npm install` e depois basta executar o servidor com `npm start`. -Para isso é necessário que o `npm` esteja instalado no sistema. +Para isso é necessário que o `npm` esteja instalado no sistema. Mas com +Docker isso não é necessário. Vamos ver como isso é configurado em um +chamado `Dockerfile`: ```Dockerfile FROM node:lts @@ -304,7 +384,7 @@ COPY . /app/ CMD [ "npm", "start" ] ``` -TODO: explicar tudo em detalhes................................................. +Sumarizando (veremos cada comando em detalhes à frente), :::{caution} A imagem escolhida é `node:lts`. Para usos além de testes locais é sempre bom @@ -325,12 +405,104 @@ suas dependências mudar ele **deveria** acompanhar essa mudança. Infelizmente o mundo da teoria é muito mais bonito e previsível que o da prática.) ::: -#### Sequência de passos -TODO: eventualmente comentar do .dockerignore, talvez não aqui +#### Criando e usando essa imagem -##### Ordenando as camadas +Lembre-se: um Dockerfile define uma **imagem**, então usamos ele para criar uma +imagem e **depois** criamos um contêiner com base nessa imagem. -TODO: mostrar trocas de camadas +Como criar uma imagem? Simples! Só executar o comando `docker build . --tag +<nome-da-imagem>`. + +Vejamos um exemplo: +``` +root@devops:/node-test# docker build . -t teste-node +DEPRECATED: The legacy builder is deprecated and will be removed in a future release. + Install the buildx component to build images with BuildKit: + https://docs.docker.com/go/buildx/ + +Sending build context to Docker daemon 2.65MB +Step 1/7 : FROM node:lts + ---> 2e805f601f2b +Step 2/7 : WORKDIR /app/ + ---> Running in cd1fea97d9bd + ---> Removed intermediate container cd1fea97d9bd + ---> 433bbc33acff +Step 3/7 : EXPOSE 3000 + ---> Running in 7f753b00ccec + ---> Removed intermediate container 7f753b00ccec + ---> b85feba0a0d5 +Step 4/7 : COPY package.json /app/package.json + ---> 5b3d5e55a62e +Step 5/7 : RUN npm install + ---> Running in 4323f8d14bbd + +added 64 packages, and audited 65 packages in 2s + +12 packages are looking for funding + run `npm fund` for details + +found 0 vulnerabilities +npm notice +npm notice New minor version of npm available! 10.2.4 -> 10.5.0 +npm notice Changelog: <https://github.com/npm/cli/releases/tag/v10.5.0> +npm notice Run `npm install -g npm@10.5.0` to update! +npm notice + ---> Removed intermediate container 4323f8d14bbd + ---> d8c047dda876 +Step 6/7 : COPY . /app/ + ---> 0d9bdde073a1 +Step 7/7 : CMD [ "npm", "start" ] + ---> Running in 0c796bc223a3 + ---> Removed intermediate container 0c796bc223a3 + ---> 094c7152f58d +Successfully built 094c7152f58d +Successfully tagged teste-node:latest +``` + +:::{note} +Perceba que há um aviso 'DEPRECATED'. No momento da escrita desse guia docker +ainda suporta usar build ao invés do buildx. Eventualmente esse guia será atualizado +para incluir ambas as opções (caso ambas ainda sejam válidas). + +Um pouco sobre o buildx será comentado na seção [Docker Compose](docker-compose). +::: + +Vamos analisar esse output: + +TODO: analisar o output asjkdajksdjkasjkd. + +Com isso devemos ter uma imagem local chamada `teste-node`. Podemos verificar isso +com `docker image ls`: + +``` +root@devops:~/node-test# docker image ls +REPOSITORY TAG IMAGE ID CREATED SIZE +teste-node latest 094c7152f58d 15 minutes ago 1.11GB +root@devops:~/node-test# +``` + +##### Criando o contêiner +Do mesmo jeito que criamos e executamos contêineres antes faremos agora, mas +passaremos mais argumentos para o comando pois eles ainda não foram demonstrados: + +TODO: falar de `docker container create` e etc. + +``` +root@devops:~/node-test# docker run --rm --name meu-container teste-node + +> docker-tutorial@1.0.0 start +> node app.js + +Escutando na porta 3000 +``` + +:::{note} +Os argumentos que passamos a mais foram `--rm` para remover automaticamente o +contêiner e `--name` para que o nome do contêiner seja um criado por nós, não +um escolhido pelo Docker. +::: + +... #### Mapeando portas @@ -340,19 +512,25 @@ isso pois por mais que uma porta seja utilizada no contêiner o host pode querer mapeá-la para outra. A verdadeira razão para usar essa instrução é para **informar** quem estiver -utilizando a imagem quais portas devem ser "publicadas". Ela serve como uma +utilizando a imagem quais portas devem ser 'publicadas'. Ela serve como uma espécie de **documentação**. ::: +##### Ordenando as camadas +TODO: mostrar trocas de camadas #### ARG e ENV +#### COPY e RUN +TODO: eventualmente comentar do .dockerignore + #### CMD vs ENTRYPOINT :::{note} Uma instrução particularmente interessante é a `HEALTHCHECK`. ::: -### *Attached* e *detached* +### Interagindo com contêineres +#### *Attached* vs *detached* #### Vendo Logs