diff --git a/source/pages/guides/docker-fundamentals.md b/source/pages/guides/docker-fundamentals.md index 5b096623ecef25a7de5af557b103fde65542fed5..6623b8e7eda970a62a8a9e06507825c0a8bcbf43 100644 --- a/source/pages/guides/docker-fundamentals.md +++ b/source/pages/guides/docker-fundamentals.md @@ -3,6 +3,9 @@ TODO: rever tudo com calma, acho que usei um monte de terminologias que não são as 'oficiais' e que tirei da cabeça. +TODO: em algum lugar (idealmente lá pro final kkkkkkkk) colocar sobre pesquisar +*samples* de Dockerfile e docker-compose.yml. + Assume-se que quem ler essa documentação é familiarizado com os conceitos básicos de Docker[^cite_docker_concepts]. @@ -10,12 +13,17 @@ 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 +TODO: rootless-docker e sobre como ele é executado (tem a ver com instalação, +que não foi comentado ainda) + ### 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 NodeJS[^cite_nodejs]. +TODO: `docker stop` e `docker run` ficariam melhores na seção 'Trabalhando com +contêineres' + Execute o comando `docker run node`. A saída deve ser similar à seguinte: ``` @@ -179,7 +187,7 @@ root@devops:~/node-test# docker rm 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# +root@devops:~/node-test# ``` ::: @@ -193,7 +201,7 @@ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES root@devops:~# docker run --rm node root@devops:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -root@devops:~# +root@devops:~# ``` ## Lidando com **imagens** @@ -341,7 +349,7 @@ root@devops:~/node-test# O terminal acima é o que chamamos de 'cliente'. :::{note} -Você pode acessar essas URLs no navegador ao invés de usar curl no terminal. +Você pode acessar essas URLs no navegador ao invés de usar `curl` no terminal. Mas não tem tanta graça ;) ::: @@ -381,14 +389,14 @@ FROM node:lts WORKDIR /app/ -EXPOSE 3000 - COPY package.json /app/package.json -RUN npm install +EXPOSE 3000 COPY . /app/ +RUN npm install + CMD [ "npm", "start" ] ``` @@ -601,10 +609,6 @@ Entretanto, antes de vermos como melhorar a interação com os contêineres vamos dar uma olhada em alguns detalhes que deixamos passar. ##### Ordenando as camadas - -TODO: MUCHO TEXTO. Tem que ter um subway surfers e mostrar 4 palavras por -vez pras pessoas acompanharem. - Talvez você já tenha criado o mesmo contêiner mais de uma vez e percebeu no output que o Docker é 'inteligente'. Ele não perderá tempo refazendo passos, afinal isso não é eficiente. @@ -622,10 +626,97 @@ as camadas **após** a camada que foi alterada (ou teve dependências alteradas) Assim não é necessário ficar buscando dependências entre camadas, e a ordenação ideal delas fica a encargo do usuário. +###### O Dockerfile fornecido Para que saber isso? Simples. O Dockerfile fornecido logo acima não necessariamente -o ideal. Por quê? Pois a instrução `EXPOSE` +o ideal. Por quê? Pois a instrução `COPY . /app/` vem antes da `RUN npm install`. + +Isso implica em sempre que o código for modificado e a imagem for reconstruída o +Docker vai re-executar o `npm install`, que no geral é bem demorado. + +Faça um teste: modifique a seguinte linha de código do arquivo `app.js`: + +```javascript + const text = `O contador eh ${counter}`; +``` + +Para algo como: + +```javascript + const text = `Contador = ${counter}`; +``` + +Depois disso execute `docker build . -t <nome-para-imagem>` de novo. O output deve +ser similar ao seguinte: + +``` +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.651MB +Step 1/7 : FROM node:lts + ---> 2e805f601f2b +Step 2/7 : WORKDIR /app/ + ---> Running in 5aa80a980286 + ---> Removed intermediate container 5aa80a980286 + ---> aa3ebb863e52 +Step 3/7 : EXPOSE 3000 + ---> Running in f67d61f55aec + ---> Removed intermediate container f67d61f55aec + ---> dcec86fcce1a +Step 4/7 : COPY package.json /app/package.json + ---> 9967b38a43c7 +Step 5/7 : RUN npm install + ---> Running in 88bad8fe183f + +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 88bad8fe183f + ---> ee748f133f4b +Step 6/7 : COPY . /app/ + ---> bc09849bf32c +Step 7/7 : CMD [ "npm", "start" ] + ---> Running in ba583883c65f + ---> Removed intermediate container ba583883c65f + ---> 86f79ca5082a +Successfully built 86f79ca5082a +Successfully tagged teste-node:latest +root@devops:~/node-test# +``` + +Perceba que ........................... + +Vamos agora mudar a ordem das camadas no Dockerfile: -........................................................ to achando q o exemplo do expose n é dos melhores +```Dockerfile +FROM node:lts + +WORKDIR /app/ + +COPY package.json /app/package.json + +EXPOSE 3000 + +COPY . /app/ + +RUN npm install + +CMD [ "npm", "start" ] +``` + +Faremos o primeiro `build`. Ele servirá para termos a base. No output você deve +perceber que tudo desde ls .......................... +TODO: o resto :::{admonition} No fim das contas o resultado é o mesmo. Mudar isso não altera o contêiner final, apenas pode acelerar o `build` em casos @@ -642,6 +733,20 @@ Vai achar o que fazer, vai. #### COPY e RUN TODO: eventualmente comentar do .dockerignore +:::{tip} +Vamos supor que você só precisa de um pequeno conjunto de seus arquivos +para executar o contêiner corretamente. Por exemplo, em um programa em C +isso poderia ser o `Makefile` e alguns dos `*.c`. + +Não é necessário (nem recomendado) copiar mais arquivos do que o necessário, +afinal isso não é eficiente. Uma solução para isso é explicitar com o `COPY` +cada um dos arquivos necessários, ou diretórios se tudo neles for necessário. + +Se você já tem familiaridade com o Git provavelmente conhece o arquivo +`.gitignore`. Com docker existe o arquivo `.dockerignore` para arquivos +não serem copiados com a instrução `COPY`. +::: + #### CMD vs ENTRYPOINT :::{seealso} @@ -705,7 +810,7 @@ não há por que mexer ninguém irá mexer. ::: ### O arquivo `docker-compose.yml` -Aqui vamos longe; +Aqui vamos longe. ### Por que agora? Por que ver toda a parte difícil antes de `compose`? @@ -739,7 +844,7 @@ ferramentas como GitLabCI[^cite_gitlab_ci] para realizar esse deploy com qualquer *merge* na branch `main`, por exemplo. ::: -### Produção e Desenvolvimento +### Ciclo de desenvolvimento ## TODO: Fernando comentou sobre docker debian12 em host debian9 -> estudar