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

feat(docker-fundamentals): progress


Signed-off-by: default avatarMarcus V. <mvrp21@inf.ufpr.br>
parent 3eedb613
No related branches found
No related tags found
No related merge requests found
......@@ -56,7 +56,7 @@ html_theme = "furo"
html_static_path = ["_static", "_static/fonts/iosevka-fixed/"]
html_css_files = ["fonts/iosevka-fixed/iosevka-fixed.css", "svgbob.css"]
html_logo = "_static/root-logo.png"
html_logo = "_static/c3sl.png"
html_theme_options = {
"sidebar_hide_name": True,
"source_edit_link": "https://gitlab.c3sl.ufpr.br/c3sl/c3docs/devops/-/blob/main/source/{filename}",
......
# DevOps do C3SL
```{image} _static/root-logo.png
:align: center
:alt: Root
:width: 200px
```
```{image} _static/c3sl.png
:align: center
:alt: C3SL UFPR
:target: https://www.c3sl.ufpr.br
:width: 150px
:width: 500px
```
```{toctree}
......
# Dockarizando uma aplicação
......@@ -6,7 +6,7 @@ básicos de Docker[^cite_docker_concepts].
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
## Trabalhando com **contêineres**
### 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
......@@ -104,7 +104,7 @@ Vamos analisar esse output:
de *entrypoint*, que veremos mais à frente. Por enquanto veja esse comando
apenas como um script que incia tudo o que o contêiner precisa.
:::{note}
:::{hint}
Para mais opções do comando `docker ps` basta executar `docker ps --help`.
:::
......@@ -130,7 +130,7 @@ undefined
Para sair da *shell* interativa do Node basta teclar `Ctrl+D`.
:::{note}
:::{hint}
Para mais opções do comando `docker run` basta executar `docker run --help`.
:::
......@@ -160,7 +160,7 @@ Note que tanto o identificador do nome quando do id do contêiner servem.
#### Removendo contêineres automaticamente
Para remover automaticamente um contêiner que você executou é só passar a
flag `--rm` para o comando `docker run <imagem>`.
flag `--rm` para o comando `docker run`.
```
root@devops:~# docker ps -a
......@@ -171,7 +171,7 @@ CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
root@devops:~#
```
## Lidando com imagens
## Lidando com **imagens**
Como comentado anteriormente, imagens Docker são construídas por camadas.
Essencialmente 'cada camada é uma linha de um script'. O que ocorre sempre que
......@@ -212,20 +212,154 @@ node latest ba29744b7cd0 3 days ago 1.1GB
root@devops:~#
```
### Criando uma imagem com um Dockerfile
TODO: exemplo com backend Node
:::{hint}
Caso você queira baixar uma imagem sem necessariamente criar um contêiner para
ela naquele momento basta executar `docker pull` (versão curta de `docker image
pull`).
:::
### Criando imagens: o arquivo **Dockerfile**
#### Pré-requisitos
Para acompanhar os próximos passos utilizaremos um código simples em NodeJS.
Não é necessário conhecer Node, mas deixa a experiência mais tranquila.
Crie um diretório, nele colocaremos dois arquivos. O primeiro:
```javascript
const express = require('express');
const fs = require('fs');
const app = express();
const FILENAME = 'texto.txt';
let counter = 0;
// Retorna o contador
app.use('/ler', (req, res) => {
console.log(`[LEITURA] contador eh ${counter}`);
const text = fs.readFileSync(FILENAME);
res.status(200).json({ texto: text, contador: counter });
});
// Escreve um texto no arquivo
app.use('/escrever', (req, res) => {
console.log(`[ESCRITA] contador foi de ${counter} para ${++counter}`);
const text = `O contador eh ${counter}`;
fs.writeFileSync(FILENAME, text);
res.status(200).json({ texto: text, contador: counter });
});
// Servidor escuta na porta 3000
app.listen(3000, () => {
fs.writeFileSync(FILENAME, 'O arquivo nao foi modificado!');
console.log('Escutando na porta 3000')
});
```
Em suma, o código acima cria um servidor que escuta na porta 3000, e possui
duas operações: ler e escrever um arquivo específico no sistema de arquivos.
Esse código deve ser salvo em um arquivo chamado `app.js`.
Além do código, o seguinte texto deve estar em outro arquivo chamado
`package.json`:
```json
{
"name": "docker-tutorial",
"version": "1.0.0",
"description": "Backend simples para brincar com docker.",
"main": "app.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"nodejs",
"express",
"docker"
],
"author": "mvrp21@inf.ufpr.br",
"license": "GPL-3.0"
}
```
Pronto! Já podemos iniciar essa seção.
#### 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.
```Dockerfile
FROM node:lts
```
:::{caution}
A imagem escolhida é `node:lts`. Para usos além de testes locais é sempre bom
mudar a tag `lts` para uma versão específica da imagem.
Isso pois `lts` é uma **tag dinâmica**. Hoje essa tag aponta para uma versão
específica (20.11.1 no momento) da escrita desse parágrafo, mas conforme o
tempo passa a versão LTS (Long Term Support[^cite_lts]) mudará; e não é
impossível que essa mudança quebre a aplicação.
Isso é particularmente ruim para aplicações que ficaram paradas por um tempo,
pois quando o contêiner for executado de novo ele procurará a versão `lts` da
imagem, que pode não ser mais compatível com a versão da época em que o projeto
era ativo.
#### EXPOSE <PORT>
(Claro, o ideal é manter um projeto atualizado, sempre que a versão LTS de
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.)
:::
#### Camadas
##### Ordenando as camadas
#### Mapeando portas
:::{attention}
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
mapeá-la para outra.
### *Attatched* e *detatched*
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
espécie de **documentação**.
:::
### *Attached* e *detached*
#### Vendo Logs
## Persistindo mudanças no disco com volumes
## Disco persistente com **volumes**
## Uma introdução às redes
### Tipos de volumes
## Uma introdução às **redes**
## Docker Compose
Como orquestrar múltiplos contêineres elegantemente?
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
comandos longos:
```
....................................
```
Um bom programador teria preguiça de executar esses comandos todos, e dado que
a configuração para os contêineres será sempre a mesma ele provavelmente
acabaria criando um script que lê um arquivo de configuração para ele e os
executa corretamente.
Felizmente, já existe uma ferramenta nativa para orquestrar múltiples
contêineres com um único arquivo de configuração, com comandos curtos: `docker
compose`.
:::{attention}
docker-compose vs. docker compose
:::
### `docker-compose.yml`
...
......@@ -249,6 +383,8 @@ ferramentas como GitLabCI[^cite_gitlab_ci] para realizar esse deploy com
qualquer *merge* na branch `main`, por exemplo.
:::
## TODO: Fernando comentou sobre docker debian12 em host debian9 -> estudar
## TODO: Colinha de Docker
- `docker run <nome-da-imagem>:<tag>`: Cria e executa um contêiner com base na imagem com
versão especificada pela *tag*.
......@@ -266,3 +402,5 @@ qualquer *merge* na branch `main`, por exemplo.
[^cite_docker_install]: [Instalando Docker](https://docs.docker.com/engine/install/).
[^cite_nodejs]: [NodeJS](https://nodejs.org/).
[^cite_docker_hub]: [DockerHub](https://hub.docker.com/).
[^cite_expose]: [Instrução EXPOSE](https://docs.docker.com/reference/dockerfile/#expose).
[^cite_lts]: [Long Term Support](https://en.wikipedia.org/wiki/Long-term_support).
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment