Skip to content
Snippets Groups Projects
Commit fb9ff3d6 authored by mvrp21's avatar mvrp21
Browse files

feat(docker-fundamentals): im tired


Signed-off-by: default avatarMarcus V. <mvrp21@inf.ufpr.br>
parent 8c3ea57f
No related branches found
No related tags found
No related merge requests found
# Fundamentos do Docker # Fundamentos do Docker
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.
Assume-se que quem ler essa documentação é familiarizado com os conceitos Assume-se que quem ler essa documentação é familiarizado com os conceitos
básicos de Docker[^cite_docker_concepts]. básicos de Docker[^cite_docker_concepts].
...@@ -337,6 +340,11 @@ root@devops:~/node-test# ...@@ -337,6 +340,11 @@ root@devops:~/node-test#
O terminal acima é o que chamamos de 'cliente'. O terminal acima é o que chamamos de 'cliente'.
:::{note}
Você pode acessar essas URLs no navegador ao invés de usar curl no terminal.
Mas não tem tanta graça ;)
:::
Voltando ao primeiro terminal, o output deve ser similar a esse: Voltando ao primeiro terminal, o output deve ser similar a esse:
``` ```
...@@ -469,7 +477,7 @@ Um pouco sobre o buildx será comentado na seção [Docker Compose](docker-compo ...@@ -469,7 +477,7 @@ Um pouco sobre o buildx será comentado na seção [Docker Compose](docker-compo
Vamos analisar esse output: Vamos analisar esse output:
TODO: analisar o output asjkdajksdjkasjkd. ............................................................................
Com isso devemos ter uma imagem local chamada `teste-node`. Podemos verificar isso Com isso devemos ter uma imagem local chamada `teste-node`. Podemos verificar isso
com `docker image ls`: com `docker image ls`:
...@@ -481,11 +489,58 @@ teste-node latest 094c7152f58d 15 minutes ago 1.11GB ...@@ -481,11 +489,58 @@ teste-node latest 094c7152f58d 15 minutes ago 1.11GB
root@devops:~/node-test# root@devops:~/node-test#
``` ```
##### Criando o contêiner ##### Criando e usando 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: Para criar um contêiner com base em uma imagem sem executá-lo imediatamente
existe o comando `docker container create <imagem>`, e sua versão curta:
`docker create <imagem>`.
```
root@devops:~/node-test# docker create --name nome-legal teste-node
```
No caso acima também escolhemos um nome para o contêiner com `--name`, mas
esse argumento não é necessário para o comando. Podemos ver esse contêiner
com `docker ps -a`:
```
root@devops:~/node-test# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa97dfc3c078 teste-node "docker-entrypoint.s…" 10 minutes ago Created nome-legal
root@devops:~/node-test#
```
Como colocá-lo em execução?
Qualquer contêiner que estiver parado pode ser iniciado com o comando `docker
start <identificador>`:
```
root@devops:~/node-test# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa97dfc3c078 teste-node "docker-entrypoint.s…" 26 minutes ago Created nome-legal
root@devops:~/node-test# docker start nome-legal
nome-legal
root@devops:~/node-test# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
fa97dfc3c078 teste-node "docker-entrypoint.s…" 26 minutes ago Up 1 second 3000/tcp nome-legal
root@devops:~/node-test#
```
:::{admonition} Socorro! Não consigo dar `Ctrl + C`!!!
:class: danger
Sim, por padrão seu terminal ficará preso aos logs do contêiner. Veremos logo à
frente como mudar esse comportamento.
Em outro terminal você deve executar `docker stop <identificador>`. Pode levar
uns segundos mas o contêiner vai parar e seu terminal será devolvido.
:::
###### Fazendo como antes
TODO: falar de `docker container create` e etc. Também é possível executar contêineres do mesmo jeito de antes. Dessa vez
passaremos mais argumentos para o comando pois eles ainda não foram
demonstrados:
``` ```
root@devops:~/node-test# docker run --rm --name meu-container teste-node root@devops:~/node-test# docker run --rm --name meu-container teste-node
...@@ -502,11 +557,21 @@ contêiner e `--name` para que o nome do contêiner seja um criado por nós, nã ...@@ -502,11 +557,21 @@ contêiner e `--name` para que o nome do contêiner seja um criado por nós, nã
um escolhido pelo Docker. um escolhido pelo Docker.
::: :::
... Para parar esse contêiner é só rodar `docker stop <identificador>` em outro
terminal.
#### Mapeando portas #### Mapeando portas
:::{attention} Se você é curioso e já sabe como o programa deveria funcionar, deve ter
percebido que acessar `localhost:3000/ler` ou `localhost:3000/escrever` não
funciona. Isso pois a porta está aberta no contêiner, mas não no host.
Na verdade, podemos ver quais portas estão sendo utilizadas no sistema com
`netstat -tnlp`. A menos que outro programa esteja utilizando a porta 3000
não deve haver nenhuma linha do output com a porta 3000.
:::{admonition} Mas e a instrução `EXPOSE` que vimos antes?
:class: attention
A instrução `EXPOSE <PORTA>`[^cite_expose] **não expõe** de verdade as portas, A instrução `EXPOSE <PORTA>`[^cite_expose] **não expõe** de verdade as portas,
isso pois por mais que uma porta seja utilizada no contêiner o host pode querer isso pois por mais que uma porta seja utilizada no contêiner o host pode querer
mapeá-la para outra. mapeá-la para outra.
...@@ -516,8 +581,62 @@ utilizando a imagem quais portas devem ser 'publicadas'. Ela serve como uma ...@@ -516,8 +581,62 @@ utilizando a imagem quais portas devem ser 'publicadas'. Ela serve como uma
espécie de **documentação**. espécie de **documentação**.
::: :::
O que precisamos é passar um argumento ou flag para mapear a porta do contêiner
para o host. Essa flag é `--port <PORTAHOST>:<PORTACONTAINER>`. O `--port` pode
ser abreviado para `-p`.
Vejamos um exemplo:
```
```
Agora
```
```
Pronto! Conseguimos criar uma imagem Docker para uma aplicação NodeJS!
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 ##### Ordenando as camadas
TODO: mostrar trocas de 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.
Uma camada de uma imagem pode depender de algo. Por exemplo uma camada que se
refere a uma instrução `COPY` depende dos arquivos que serão copiados. Se nenhum
arquivo for modificado então o contêiner criado com aquela imagem já tem os
arquivos necessários, logo não há porque fazer a cópia.
Entretanto, caso um arquivo seja modificado a instrução `COPY` deve executar
de novo, naturalmente.
O que isso implica nas demais camadas? Por questões de simplificação **todas**
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.
Para que saber isso? Simples. O Dockerfile fornecido logo acima não necessariamente
o ideal. Por quê? Pois a instrução `EXPOSE`
........................................................ to achando q o exemplo do expose n é dos melhores
:::{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
que essa ordenação.
> 'Ah... mas se no final o efeito é o mesmo, só não é tão eficiente, então não
> faz diferença'.
Vai achar o que fazer, vai.
:::
#### ARG e ENV #### ARG e ENV
#### COPY e RUN #### COPY e RUN
...@@ -525,8 +644,8 @@ TODO: eventualmente comentar do .dockerignore ...@@ -525,8 +644,8 @@ TODO: eventualmente comentar do .dockerignore
#### CMD vs ENTRYPOINT #### CMD vs ENTRYPOINT
:::{note} :::{seealso}
Uma instrução particularmente interessante é a `HEALTHCHECK`. TODO: Uma instrução particularmente interessante é a `HEALTHCHECK`.
::: :::
### Interagindo com contêineres ### Interagindo com contêineres
...@@ -534,9 +653,12 @@ Uma instrução particularmente interessante é a `HEALTHCHECK`. ...@@ -534,9 +653,12 @@ Uma instrução particularmente interessante é a `HEALTHCHECK`.
#### Vendo Logs #### Vendo Logs
#### Utilizando `docker exec`
## Disco persistente com **volumes** ## Disco persistente com **volumes**
### Tipos de volumes ### Tipos de volumes
#### Bind Mounts
## Uma introdução às **redes** ## Uma introdução às **redes**
...@@ -544,7 +666,7 @@ Uma instrução particularmente interessante é a `HEALTHCHECK`. ...@@ -544,7 +666,7 @@ Uma instrução particularmente interessante é a `HEALTHCHECK`.
Como orquestrar múltiplos contêineres elegantemente? Como orquestrar múltiplos contêineres elegantemente?
Vamos supor que desejamos executar aquele mesmo contêiner com base na imagem do Vamos supor que desejamos executar aquele mesmo contêiner com base na imagem do
Dockerfile que foi criado logo acima. Seria necessária a seguinte sequência de Dockerfile que foi criado logo acima. Seria necessára a seguinte sequência de
comandos longos: comandos longos:
``` ```
...@@ -564,15 +686,44 @@ compose`. ...@@ -564,15 +686,44 @@ compose`.
docker-compose vs. docker compose docker-compose vs. docker compose
::: :::
### `docker-compose.yml` Na verdade, mesmo com um único contêiner, para o caso de uso para os projetos do
... C3SL ainda é melhor usar `compose`. Isso pois ele é mais simples de executar, tem
um arquivo de configuração descritivo e no geral facilita a vida de quem usa.
:::{attention}
O problema com isso é que geralmente uma única pessoa aprende o suficiente de
Docker para fazer essa configuração inicial, e depois todos aceitam que funciona
e usam, mas eventualmente quem fez e conhece Docker sai.
Um dia algum problema surge, com ele a necessidade de mexer no Dockerfile ou no
docker-compose.yml, e muito tempo é perdido tentando arrumar algo que deveria
facilitaria o trabalho caso todos conhecessem.
Isso não é problema com Docker em si, mas sim com não conhecer uma tecnologia
essencial para o projeto. O que é relativamente compreensível, se funciona e
não há por que mexer ninguém irá mexer.
:::
### O arquivo `docker-compose.yml`
Aqui vamos longe;
### Por que agora?
Por que ver toda a parte difícil antes de `compose`?
Para entender como ele funciona, por que ele existe e o que acontece por
debaixo dos panos. Além disso saber `compose` não exclui a necessidade de saber
o 'docker puro'.
Por exemplo, se você tem uma aplicação com vários contêineres e precisa atualizar
algo dentro de um deles, você (idealmente) não vai parar todos os outros com
`docker compose down`, mas vai parar apenas o necessário com `docker stop`.
## TODO: Utilizando um registry ## TODO: Utilizando um registry
Falar de `pull`, `login`, `push` e etc. Falar de `pull`, `login`, `push` e etc.
## Exemplo de *deploy* manual ## Exemplo de *deploy* manual
TODO: fazer o exemplo TODO: fazer o exemplo (quadro de avisos????)
:::{admonition} Esse não é necessariamente o melhor método. :::{admonition} Esse não é necessariamente o melhor método.
:class: note :class: note
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment