Docker

Gerenciando Containers
Voltar

Material complementar:

  • Conteúdo no YouTube: Acesse
  • Curso com certificado na Udemy (Docker e Docker Compose, teoria e prática: Curso rápido): Acesse

Conceito:

Ao instalar software, ele precisa ser compatível com sistema operacional da máquina para funcionar. Um software feito especificamente para MacOS não funcionará no Windows, pois sistema operacional base não é compatível. Docker é programa/camada entre sistema operacional e programas. Ele é base, que permite rodar seus programas Docker (containers), que são como caixinhas fechadas (isoladas) contendo tudo o que software precisa para funcionar: sistema, configurações, arquivos e programas. Esses containers não se comunicam diretamente com o sistema da máquina (host docker), mas sim ao Docker. Então, possuindo Docker instalado, seus programas Docker (containers) funcionarão e não dependerão de compatibilidade com sistema operacional da máquina. Um container roda em qualquer sistema com Docker, e seu isolamento trás segurança, não afetando o sistema principal, além de fácil manuseio (exportar) entre diferentes máquinas. Dentro de container, geralmente há:

  • Sistema operacional base;
  • Programas (geralmente CLI) compatíveis com esse sistema operacional;
  • Configurações e personalizações desses programas;
  • Pastas para armazenamento de dados (volumes);
  • Configurações de rede (para comunicação do container com outras máquinas - físicas, VMs ou outros containers).

Docker geralmente é utilizado em servidores Linux que não têm interface gráfica, apenas linha de comando. Essas máquinas normalmente estão hospedadas online, em clouds como Amazon AWS, Microsoft Azure e Google Cloud Platform (GCP). Containers Dockers criados nessas máquinas geralmente são conectados a projetos locais (como aplicações web ou APIs), onde o desenvolvedor simplesmente conecta seu projeto local a esse container dessa máquina servidor em cloud, dispensando instalar e configurar dependências na máquina local. Ou container pode servir especificamente para atuar como complemento a máquina servidor em cloud, disponibilizando seus programas e recursos (iac infrastructure as code - IaC).


Construção de container:

Containers possuem ciclo de vida (up, exited). Pode-se construir container do zero (maneira 2), criando arquivo Dockerfile, contendo conteúdo passo a passo de toda estrutura do container (Image, sistema operacional, programas, configurações, volumes, rede, etc). Ao executar Dockerfile, criará Image (planta baixa do container) que, ao executada, criará container. Ou pode-se baixar Images prontas (maneira 1) através de repositório registry (loja), como Docker Hub. Ao executar Image baixada pronta todo container será criado, com respectivos componentes (sistema, softwares, configurações, etc). Dockerfile executado = Image executada = Container.


Instalar Docker (Ubuntu):

  1. Instalar Docker (Docker ficará no diretório '/etc/'):
    
    sudo apt update && sudo apt install ca-certificates curl -y && sudo install -m 0755 -d /etc/apt/keyrings && sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc && sudo chmod a+r /etc/apt/keyrings/docker.asc && echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null && sudo apt update && sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin -y
    
  2. Docker sem sudo: sudo groupadd docker && sudo usermod -aG docker $USER && newgrp docker
  3. Verificar Docker instalado: docker --version

Maneira 1. Criar container via Image pronta:

Baixar Image pronta, do Docker Hub, e executá-la, gerando container.


Construir container a partir de Image: docker run -dti nome_Image:versaoOpcional (baixará Image se não houver, executando-a e construindo container. Sempre construirá novo container, mesmo que já exista um com mesmo nome)
- Com nome personalizado: --name nome_container
- Com variáveis de ambiente: -e VARIAVEL=valor
- Com porta personalizada: -p portaHost:portaContainer
- Com rede personalizada: --network nome_rede
- Com volume compartilhado: -v /caminho/host:/caminho/container
- Com limite de memória: -m 512m
- Com limite de CPU: --cpus="1.0"

Listar Containers: docker ps -a (remover -a para somente containers em execução)
Ver informações do container: docker inspect idContainer

Iniciar container: docker start idContainer (sempre usar quando container já existir)
Parar container: docker stop idContainer
Reiniciar container: docker restart idContainer
Remover container parado: docker rm idContainer (-f para forçar remoção de containers em execução)

Entrar no container: docker exec -ti idContainer bash (Ctrl+d para sair do container)

Outros parâmetros do comando docker 'run' e 'exec':

  • -d: executa container em background (detached);
  • -f: especifica local do Dockerfile;
  • -t: tag (apelido) da Image;
  • -i: modo interativo, como shell para comandos;
  • -ti: TTY, utilizar emulador de terminal;
  • --rm: sobrescreve container com novo, caso já exista antigo similar;
  • -v: mapeia volumes do container para máquina host (diretorioHost:diretorioContainer). São pastas sincronizadas, em tempo real, entre máquina host e container.

Maneira 2. Criar container via Dockerfile e Image:

Criar arquivo Dockerfile, com instruções de Image. Executar Dockerfile, construindo Image e, com isso, executar Image, criando container. Sintaxe do nome da Image é 'usuario/nomeImageRepositorio:versaoImage' (versão padrão é latest). Arquivo com nome Dockerfile (sem extensão), contém instruções para construir Image do container. Funcionamento dependente de indentação de código. Possui a sintaxe:


# 1. Image base obrigatória
FROM nomeImage:versaoImage

# 2. Labels (metadados, como autor, versão, descrição)
LABEL maintainer="email@exemplo.com"
LABEL version="1.0"
LABEL description="Descrição da Image"

# 3. Variáveis de ambiente
ENV VARIAVEL1=valor1 \
    VARIAVEL2=valor2

# 4. Argumentos de build (diferente de ENV – usados só na criação da Image)
ARG VERSAO_PYTHON=3.11

# 5. Atualiza pacotes e instala dependências (durante a criação da Image)
RUN apt-get update && apt-get install -y \
    pacote1 \
    pacote2

# 6. Copia arquivos do host para a Image
COPY ./diretorioLocal/ /diretorioContainer/

# 7. Alternativa: baixar arquivos diretamente
ADD https://site.com/arquivo.tar.gz /tmp/arquivo.tar.gz

# 8. Define o diretório de trabalho padrão
WORKDIR /diretorioContainer

# 9. Expõe portas (só para documentação — usar -p no docker run)
EXPOSE 80
EXPOSE 443

# 10. Define volumes (ponto de montagem — criar pasta compartilhada com o host)
VOLUME ["/dados"]

# 11. Define o container para rodar sempre como usuário específico (segurança)
USER root  # ou: USER appuser

# 12. Entrypoint (comando principal fixo, pode receber parâmetros via CMD)
ENTRYPOINT ["./entrypoint.sh"]

# 13. CMD (comando ou argumentos que serão passados ao ENTRYPOINT)
CMD ["--modo=prod"]

# 14. Healthcheck (verifica se o container está saudável)
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
  CMD curl --fail http://localhost:80/health || exit 1

Após criar Dockerfile, executar comando para construir Image e, com isso, criar container:


Construir Image a partir do Dockerfile: docker build -t nome_da_Image:versaoOpcional /caminho/pastaDockerfile

Listar Images: docker images
Remover Image: docker rmi nome_da_Image:versaoOpcional
Nomear Image: docker image tag nomeAtual novoNome

Outros comandos:
Listar redes: docker network ls
Conectar container a rede: docker network connect nomeRede idContainer ('disconnect' para desconectar)

Criar Volume: docker volume create nomeVolume
Listar Volumes: docker volume ls
Ver dados do Volume: docker volume inspect nomeVolume
Remover Volume: docker volume rm nomeVolume
Copiar arquivos do host para o container: docker cp /caminho/arquivo idContainer:/caminho/destino (o contrário para copiar do container para host)

Exportar todo container: docker export idContainer > nomeArquivo.tar
Importar container: docker import nomeArquivo.tar nomeImage:versaoOpcional
Exportar Image: docker save -o nomeArquivo.tar nomeImage:versaoOpcional
Importar Image: docker load -i nomeArquivo.tar

Conectar ao Docker Hub: docker login (digitar usuário e senha, 'logout' para desconectar)
Pesquisar Image no Docker Hub: docker search nomeImage
Baixar Image do Docker Hub: docker pull nomeImage:versaoOpcional
Enviar Image ao Docker Hub: docker push nomeImage:versaoOpcional

Laboratórios:

  1. Criar e acessar container Ubuntu, via Image pronta:
    
    1.Criar container: docker run -dti ubuntu
    2.Listar containers: docker ps -a
    3.Entrar no container: docker exec -ti idContainer bash
    4.Verificar versão do Ubuntu: cat /etc/*-release
    5.Sair do container: Ctrl+d
    6.Parar container: docker stop idContainer
    
  2. Criar e acessar container Ubuntu, via criação de Dockerfile, Image e container:
    
    1.Criar Dockerfile:
    FROM ubuntu
    RUN apt update && apt install htop -y
    CMD ["bash"]
    
    2.Criar Image: docker build . -t ubuntu-htop
    3.Listar Images: docker images
    4.Criar e acessar container: docker run -di ubuntu-htop
    5.Listar containers: docker ps -a
    6.Entrar no container: docker exec -ti idContainer bash
    7.Acessar htop: htop (q para sair)
    8.Sair do container: Ctrl+d
    9.Parar container: docker stop idContainer
    
  3. Criar 2 containers, um servidor com nginx e outro cliente curl para acessá-lo. Criação via Images prontas:
    
    1.Criar rede: docker network create minha-rede
    2.Criar container servidor: docker run -dti --name servidor --network minha-rede nginx
    3.Criar container cliente: docker run -dti --name cliente --network minha-rede curlimages/curl sh
    4.Acessar servidor via cliente: docker exec -ti cliente curl http://servidor
    4.2.Entrar no cliente: docker exec -ti cliente sh
    5.No cliente, acessar servidor: curl http://servidor
    6.Sair do cliente: Ctrl+d
    
    7.Parar containers: docker stop servidor cliente
    8.Remover containers: docker rm servidor cliente
    9.Parar rede: docker network rm minha-rede
    
  4. Criar 2 containers, um servidor com nginx e outro cliente curl para acessá-lo. Criação via Dockerfile:
    
    1.Criar rede: docker network create minha-rede
    2.Criar Dockerfile do servidor:
    FROM nginx
    RUN echo '<h1>Servidor Nginx UB Social</h1>' > /usr/share/nginx/html/index.html
    
    3.Criar Image do servidor: docker build -t imgservidor .
    4.Apagar Dockerfile: rm Dockerfile
    5.Criar Dockerfile do cliente:
    FROM alpine
    RUN apk add --no-cache curl
    CMD ["sh"]
    
    6.Criar Image do cliente: docker build -t imgcliente .
    7.Criar container servidor: docker run -dti --name servidor --network minha-rede imgservidor
    8.Criar container cliente: docker run -dti --name cliente --network minha-rede imgcliente
    9.Acessar servidor via cliente: docker exec -ti cliente curl http://servidor
    9.2.Entrar no cliente: docker exec -ti cliente sh
    10.No cliente, acessar servidor: curl http://servidor
    11.Sair do cliente: Ctrl+d
    
    12.Parar containers: docker stop servidor cliente
    13.Remover containers: docker rm servidor cliente
    14.Parar rede: docker network rm minha-rede
    
  5. Criar 2 containers, um servidor com Apache e outro cliente curl para acessá-lo via portas de rede. Criação via Images prontas:
    
    1.Criar rede: docker network create minha-rede
    2.Criar container servidor (porta 8080 da máquina host conectará com 80 do container): docker run -dti --name servidor --network minha-rede -p 8080:80 httpd
    3.Criar container cliente: docker run -dti --name cliente --network minha-rede curlimages/curl sh
    4.Acessar servidor via cliente: docker exec -ti cliente curl http://servidor:80
    4.2.Entrar no cliente: docker exec -ti cliente sh
    5.No cliente, acessar servidor: curl http://servidor:80
    6.Sair do cliente: Ctrl+d
    7.Na máquina host, acessar servidor: curl http://localhost:8080
    
    8.Parar containers: docker stop servidor cliente
    9.Remover containers: docker rm servidor cliente
    10.Parar rede: docker network rm minha-rede
    
  6. Criar 2 containers, um servidor com Apache e outro cliente curl para acessá-lo via portas de rede. Criação via Dockerfile:
    
    1.Criar rede: docker network create minha-rede
    2.Criar Dockerfile do servidor:
    FROM httpd
    RUN echo '<h1>Servidor Apache UB Social</h1>' > /usr/local/apache2/htdocs/index.html
    
    3.Criar Image do servidor: docker build -t imgservidor .
    4.Apagar Dockerfile: rm Dockerfile
    5.Criar Dockerfile do cliente:
    FROM alpine
    RUN apk add --no-cache curl
    CMD ["sh"]
    
    6.Criar Image do cliente: docker build -t imgcliente .
    7.Criar container servidor: docker run -dti --name servidor --network minha-rede -p 8080:80 imgservidor
    8.Criar container cliente: docker run -dti --name cliente --network minha-rede imgcliente
    9.Acessar servidor via cliente: docker exec -ti cliente curl http://servidor:80
    9.2.Entrar no cliente: docker exec -ti cliente sh
    10.No cliente, acessar servidor: curl http://servidor:80
    11.Sair do cliente: Ctrl+d
    12.Na máquina host, acessar servidor: curl http://localhost:8080
    
    13.Parar containers: docker stop servidor cliente
    14.Remover containers: docker rm servidor cliente
    15.Parar rede: docker network rm minha-rede
    
  7. Criar container com volume. Criação via Image pronta:
    
    1.Criar pasta de volume na máquina host: mkdir -p ~/meu-site
    2.Criar arquivo dentro da pasta volume: echo '<h1>Meu site UB Social criado fora do container</h1>' > ~/meu-site/index.html
    3.Criar container com volume sincronizado com máquina host: docker run -dti --name servidor-volume -p 8080:80 -v ~/meu-site:/usr/local/apache2/htdocs/ httpd
    4.Acessar servidor via navegador: curl http://localhost:8080
    5.Modificar arquivo index.html na máquina host: echo '<h1>Meu site UB Social atualizado fora do container</h1>' > ~/meu-site/index.html
    6.Entrar no container: docker exec -ti servidor-volume sh
    7.No container, acessar pasta volume: cat /usr/local/apache2/htdocs/index.html
    8.No container, modificar arquivo index.html: echo '<h1>Meu site UB Social atualizado dentro do container</h1>' > /usr/local/apache2/htdocs/index.html
    9.Sair do container: Ctrl+d
    10.Na máquina host, acessar arquivo index.html: cat ~/meu-site/index.html
    11.Acessar servidor via navegador: curl http://localhost:8080
    
    12.Parar container: docker stop servidor-volume
    13.Remover container: docker rm servidor-volume
    14.Remover pasta de volume: rm -rf ~/meu-site
    15.Remover Image: docker rmi imgservidor
    16.Remover Dockerfile: rm Dockerfile
    17.Remover rede: docker network rm minha-rede
    
  8. Criar container com volume. Criação via Dockerfile:
    
    1.Criar pasta de volume na máquina host: mkdir -p ~/meu-site
    2.Criar Dockerfile do container com volume:
    FROM httpd
    VOLUME ["/usr/local/apache2/htdocs/"]
    
    3.Criar Image do container: docker build -t imgservidor .
    4.Criar container: docker run -dti --name servidor-volume -p 8080:80 -v ~/meu-site:/usr/local/apache2/htdocs/ imgservidor
    5.Acessar container via navegador: curl http://localhost:8080
    6.Entrar no container: docker exec -ti servidor-volume sh
    7.No container, editar arquivo index.html: echo '<h1>Meu site UB Social atualizado dentro do container</h1>' > /usr/local/apache2/htdocs/index.html
    8.Sair do container: Ctrl+d
    9.Acessar container via navegador: curl http://localhost:8080
    10.Modificar index.html na máquina host: echo '<h1>Meu site UB Social atualizado fora do container</h1>' > ~/meu-site/index.html
    11.Acessar container via navegador: curl http://localhost:8080
    12.Entrar no container: docker exec -ti servidor-volume sh
    13.No container, ver arquivo index.html: cat /usr/local/apache2/htdocs/index.html
    14.Sair do container: Ctrl+d
    15.Parar container: docker stop servidor-volume
    16.Remover container: docker rm servidor-volume
    17.Remover pasta de volume: rm -rf ~/meu-site
    
  9. Via Images prontas, criar sistema de troca de mensagens, envolvendo 3 containers:
    • Container 'postgres' armazenará banco de dados PostgreSQL;
    • Container 'api' será API backend Nodejs;
    • Container 'cliente' será frontend curl.
    • Funcionamento: cliente (curl) -> api (conecta) -> postgres (armazena dados)
    
    1.Criar rede: docker network create minha-rede
    2.Criar volume para armazenar dados: docker volume create volume-dados-postgres
    3.Criar container banco de dados:
    docker run -dti \
      --name postgres \
      --network minha-rede \
      -v volume-dados-postgres:/var/lib/postgresql/data \
      -e POSTGRES_USER=mensageiro \
      -e POSTGRES_PASSWORD=secreto123 \
      -e POSTGRES_DB=mensagensdb \
      postgres
    
    4.Criar container API backend Nodejs:
    docker run -dti \
      --name api \
      --network minha-rede \
      -w /app \
      -e DB_HOST=postgres \
      -e DB_USER=mensageiro \
      -e DB_PASS=secreto123 \
      -e DB_NAME=mensagensdb \
      node sh
    
    5.Entrar no container API: docker exec -ti api sh
    6.No container API, instalar dependências e criar servidor: npm init -y && npm install express
    7.Criar arquivo app.js:
    echo "const express = require('express');
    const app = express();
    const port = 3000;
    app.get('/', (req, res) => res.send('API de Mensagens está ativa'));
    app.listen(port, () => console.log('API rodando na porta', port));" > app.js
    
    8.Iniciar servidor API: node app.js &
    9.Sair do container API: Ctrl+d
    10.Criar container cliente:
    docker run -dti \
      --name cliente \
      --network minha-rede \
      curlimages/curl sh
    
    11.Listar containers: docker ps -a
    12.Listar volumes: docker volume ls
    13.Entrar no cliente: docker exec -ti cliente sh
    14.No cliente, acessar API: curl http://api:3000
    15.Sair do cliente: Ctrl+d
    16.Conferir volume na máquina host: sudo ls /var/lib/docker/volumes/volume-dados-postgres/_data
    17.Parar containers: docker stop postgres api cliente
    18.Remover containers: docker rm postgres api cliente
    19.Parar rede: docker network rm minha-rede
    20.Remover volume: docker volume rm volume-dados-postgres
    
  10. Subir (push) Image no Docker Hub (registry):
    
    1.Criar Dockerfile:
    FROM ubuntu
    RUN apt update && apt install -y figlet
    CMD ["bash"]
    
    2.Criar Image: docker build -t nomeusuario/novorepo .
    3.Criar repositório no Docker Hub: acessar https://hub.docker.com/repositories e criar repositório 'nomeusuario/novorepo'
    
    4.Login no Docker Hub: docker login (digitar usuário e senha, 'logout' para desconectar)
    5.Subir (push) Image para o Docker Hub: docker push nomeusuario/novorepo
    6.Verificar no Docker Hub: acessar https://hub.docker.com/r/nomeusuario/novorepo (aba "Tags" para ver versões)
    7.Criar nova versão da Image: docker tag nomeusuario/novorepo nomeusuario/novorepo:v2
    8.Subir nova versão para o Docker Hub: docker push nomeusuario/novorepo:v2
    9.Verificar nova versão no Docker Hub: acessar https://hub.docker.com/r/nomeusuario/novorepo/tags
    
    10.Criar container com Image do Docker Hub: docker run -dti --name containerUB nomeusuario/novorepo:v2
    11.Entrar no container: docker exec -ti containerUB bash
    12.Verificar instalação: figlet "UB Social"
    13.Sair do container: Ctrl+d
    
    14.Listar Images: docker images
    15.Exportar Image: docker save -o nomeusuario-novorepo.tar nomeusuario/novorepo:v2 ('ls' para verificar arquivo criado)
    16.Importar Image: docker load -i nomeusuario-novorepo.tar
    17.Exportar container: docker export containerUB > containerUB.tar ('ls' para verificar arquivo criado)
    18.Importar container: docker import containerUB.tar nomeusuario/novorepo:v1
    
    19.Parar container: docker stop containerUB
    20.Remover container: docker rm containerUB
    21.Ver ID das Images vinculadas: docker images --digests
    22.Remover Image local: docker rmi ID_IMAGE
    
  11. Criar container na Amazon AWS:
    
    --- CONTAINER NO HOST DOCKER ---
    1.Criar Dockerfile:
    FROM nginx:latest
    RUN rm -rf /usr/share/nginx/html/*
    RUN echo '<h1>UB Social</h1><p>Container com servidor nginx na AWS</p>' > /usr/share/nginx/html/index.html
    2.Criar Image e construir container:
    - docker build -t ubsocial/meu-nginx .
    - docker run -dti -p 8080:80 ubsocial/meu-nginx2
    3.Acessar nginx via host docker: curl http://localhost:8080
    
    --- CRIAR USUÁRIO AWS ---
    1.IAM / Usuários / Criar usuário
    - Nome: usuarioUB1
    - Fornecer acesso console AWS: habilitar
    - Tipo: Quero criar usuário do IAM
    - Senha do console: Senha gerada automaticamente
    Próximo
    - Permissões: Anexar políticas diretamente
    -- AmazonEC2ContainerRegistryFullAccess
    -- AmazonECS_FullAccess
    -- AdministratorAccess
    Próximo / Criar usuário / Baixar CSV
    2.Selecionar usuário / Habilitar acesso console FMA
    - Nome dispositivo: ubuntuTeste1
    - MFA device: Chave de acesso ou chave de segurança
    Próximo / Ativar via navegador
    3.Selecionar usuário / Criar chave de acesso
    - Tipo: CLI
    - Valor etiqueta descrição: Criar containers
    Criar chave de acesso / Baixar CSV
    
    --- INSTALAR AWS CLI ---
    1.curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
    2.sudo apt update && sudo apt install -y unzip
    3.unzip awscliv2.zip
    4.sudo ./aws/install
    5.aws --version
    6.aws configure
    - informar keys geradas no CSV com dados de chave de acesso do usuário
    - região: sa-east-1
    - Default output format: json
    7.Login AWS CLI: aws ecr get-login-password --region sa-east-1 | docker login --username AWS --password-stdin ID-CONTA.dkr.ecr.sa-east-1.amazonaws.com
    
    --- PUBLICAR IMAGE NA AWS ---
    1.ECR / Repositórios / Criar repositório
    - Nome: ubsocial/meu-nginx
    - Etiqueta: Mutable
    Criar
    2.No host Docker, upload Image na AWS:
    - docker tag ubsocial/meu-nginx:latest ID-CONTA.dkr.ecr.sa-east-1.amazonaws.com/ubsocial/meu-nginx:latest
    - docker push ID-CONTA.dkr.ecr.sa-east-1.amazonaws.com/ubsocial/meu-nginx:latest
    
    --- CRIAR CLUSTER FARGATE ---
    ECS / Clusters / Criar cluster
    - Nome gerado automaticamente
    - Infraestrutura: AWS Fargate (sem servidor)
    Criar
    
    --- CRIAR DEFINIÇÃO DE TAREFA ---
    ECS / Definições de tarefa / Criar nova definição de tarefa
    - Família: familia-task
    - Tipo de inicialização: AWS Fargate
    - CPU: .25vCPU
    - Memória: .5GB
    Container 1:
    - Nome: meu-nginx-container
    - URI da imagem: ID-CONTA.dkr.ecr.sa-east-1.amazonaws.com/ubsocial/meu-nginx:latest
    - Porta do container: 80
    Criar
    
    --- CRIAR SERVIÇO FARGATE ---
    ECS / Clusters / Selecionar cluster / Aba serviços / Criar
    - Família da definição de tarefa: familia-task
    - Nome do serviço gerado automaticamente
    - Provedor de capacidade: Fargate (padrão)
    - Tarefas desejadas: 1 (padrão)
    - Rede VPC: padrão
    - Sub-redes: padrão
    - IP público: habilitar (padrão)
    Criar
    
    --- HABILITAR ACESSO AO CONTAINER AWS ---
    ECS / Clusters / Selecionar cluster / Aba Serviços / Tarefas / Selecionar tarefa
    - Aba Redes: clicar no ID da ENI
    - Na ENI: clicar no grupo de segurança
    - No grupo de segurança: editar regras de entrada (adicionar nova regra)
    -- Tipo: HTTP
    -- Protocolo: TCP (padrão)
    -- Intervalo de portas: 80 (padrão)
    -- Origem: Qualquer local-IPv4
    -- 0.0.0.0/0
    Salvar regras
    
    --- ACESSAR CONTAINER AWS ---
    ECS / Clusters / Selecionar cluster / Aba Serviços / Tarefas / Selecionar tarefa
    - Aba Associações de rede: Copiar IP-AWS
    - No host docker: curl http://IP-AWS
    
    --- Exclusões ---
    1.ECS / Clusters / Selecionar cluster / Excluir cluster
    2.ECS / Definições de tarefa / Selecionar definição / familia-task / Ações / Cancelar registro
    3.ECR / Repositórios / Selecionar repositório / Excluir
    4.IAM / Usuários / Selecionar usuário / Excluir (desativar chave de acesso, e confirmar exclusão)
    5.Apagar dados locais no host docker (images, container, Dockerfile)
    

Docker Compose:

Arquivo 'docker-compose.yml' contendo toda infraestrutura (IaC) necessária de containers e seus respectivos serviços (Images, comandos, variáveis de ambiente, volumes, redes, etc). Basicamente, é uma planta baixa de vários containers configurados. Como complemento, o Docker Swarm (similar ao K8s) orquestra arquiteturas de containers em cluster. Sintaxe completa de arquivo docker-compose.yml:


version: "3.9" # Versão da sintaxe do Compose (opcional)

services: # Define os serviços (containers) do projeto
    nome_do_servico: # Nome do serviço (pode ser qualquer nome válido)
        build: # Caminho para o Dockerfile e build da Image (opcional, se quiser construir a Image)
            context: ./caminho/do/contexto # Caminho do diretório onde está o Dockerfile (obrigatório se usar build)
            dockerfile: Dockerfile # Nome do Dockerfile (opcional, se for diferente de "Dockerfile")
            args: # Argumentos passados como --build-arg
                VARIAVEL_DE_BUILD: valor

        image: nome-da-Image:tag # Nome da Image (opcional se usar build, obrigatório se for baixar do Docker Hub)
        container_name: nome_do_container # Nome fixo para o container

        command: comando_inicial # Comando a ser executado no container
        entrypoint: ["comando", "args"] # Sobrescreve o ENTRYPOINT da Image

        ports: # Mapeamento de portas host:container
            - "8080:80"

        expose: # Expõe portas internamente (sem expor para o host)
            - "80"

        environment: # Variáveis de ambiente
            - VAR1=valor
            - VAR2=valor2

        env_file: # Arquivo .env com variáveis
            - .env

        volumes: # Volumes (host:container), para persistência ou código
            - ./dados:/app/dados
            - volume-nome:/caminho/container

        networks: # Redes às quais o container estará conectado
            - minha-rede

        depends_on: # Define ordem de dependência (não garante que o serviço estará "pronto")
            - outro_servico

        restart: unless-stopped # Política de reinício (no-failure | always | unless-stopped | no)

        working_dir: /caminho # Define o diretório de trabalho dentro do container

        user: "1000:1000" # UID:GID do usuário que executa o processo no container

        stdin_open: true # Mantém STDIN aberto (modo interativo, útil para terminal)
        tty: true # Aloca um terminal TTY

        healthcheck: # Configura verificação de saúde
            test: ["CMD", "curl", "-f", "http://localhost"]
            interval: 30s
            timeout: 10s
            retries: 3
            start_period: 5s

        logging: # Configura o driver de log
            driver: "json-file"
            options:
                max-size: "10m"
                max-file: "3"

        extra_hosts: # Adiciona mapeamento de hosts (útil para DNS local)
            - "meusite.local:127.0.0.1"

volumes: # Define volumes nomeados que podem ser usados pelos serviços
    volume-nome: # Nome pode ser qualquer identificador válido
        driver: local # Driver do volume (default é local)
        name: volume_real # Nome real do volume

networks: # Define redes personalizadas
    minha-rede:
        driver: bridge # Tipo de rede (bridge, overlay, host). Padrão é bridge.
        name: rede_real # Nome real da rede

Após criar docker-compose.yml, executar comandos para gerenciar serviços:


Executar docker-compose.yml: docker compose up -d ('-f' para especificar diretório do arquivo, 'down' para parar e remover containers)
Entrar no container: docker compose exec nomeContainer bash (ou sh)

Iniciar containers: docker compose start ('stop' para parar, 'restart' para reiniciar)
Listar containers: docker compose ps ('version' para ver versão do compose)
Apenas construir Image: docker compose build ('pull' para somente baixar Images, 'push' para enviar Images)
Remover containers: docker compose rm (-f para forçar remoção, -v para remover volumes)

Várias réplicas de container: docker compose up --scale nomeContainer=N -d (N é nº de réplicas)

Laboratórios:

  1. Criar 2 containers via docker-compose.yml:
    • Container servidor nginx, com aplicação web;
    • Container cliente curl, para acessar servidor.
    
    1.Criar arquivo docker-compose.yml:
    services:
        servidor:
            image: nginx
            container_name: servidor
            ports:
                - "8080:80"
            networks:
                - rede1
    
        cliente:
            image: alpine
            container_name: cliente
            networks:
                - rede1
            command: sh -c "apk add --no-cache curl && tail -f /dev/null"
    
    networks:
        rede1:
    
    2.Executar docker-compose.yml: docker compose up -d
    3.Listar containers: docker compose ps
    4.Entrar no servidor: docker compose exec servidor sh
    5.Acessar aplicação web: curl http://localhost
    6.Sair do servidor: Ctrl+d
    
    7.Entrar no cliente: docker compose exec cliente sh
    8.No cliente, acessar servidor: curl http://servidor
    9.Sair do cliente: Ctrl+d
    
    10.Parar containers: docker compose stop
    11.Remover containers: docker compose rm -f
    12.Remover rede: docker network rm rede1
    13.Remover Images: docker rmi nginx alpine
    14.Remover arquivo docker-compose.yml: rm docker-compose.yml
    
  2. Recriar estrutura do item 9 acima (sistema de mensagens):
    
    1.Criar arquivo docker-compose.yml:
    services:
        postgres:
            image: postgres
            container_name: postgres
            environment:
                POSTGRES_USER: mensageiro
                POSTGRES_PASSWORD: secreto123
                POSTGRES_DB: mensagensdb
            volumes:
                - volume-dados-postgres:/var/lib/postgresql/data
            networks:
                - minha-rede
    
        api:
            image: node
            container_name: api
            working_dir: /app
            command: sh -c "npm init -y && npm install express && echo \"const express = require('express'); const app = express(); const port = 3000; app.get('/', (req, res) => res.send('API de Mensagens está ativa')); app.listen(port, () => console.log('API rodando na porta', port));\" > app.js && node app.js"
            environment:
                DB_HOST: postgres
                DB_USER: mensageiro
                DB_PASS: secreto123
                DB_NAME: mensagensdb
            depends_on:
                - postgres
            networks:
                - minha-rede
    
        cliente:
            image: curlimages/curl
            container_name: cliente
            command: sh
            tty: true
            networks:
                - minha-rede
    
    volumes:
        volume-dados-postgres:
    
    networks:
        minha-rede:
    
    2.Executar docker-compose.yml: docker compose up -d
    3.Listar containers: docker compose ps
    
    4.Entrar no container api: docker compose exec api sh
    5.Verificar se arquivo app.js está executando: ps aux | grep node
    6.Acessar servidor: curl http://localhost:3000
    7.Sair do api: Ctrl+d
    
    8.Acessar volume na máquina host: sudo ls /var/lib/docker/volumes/mateus_volume-dados-postgres/_data
    
    9.Entrar no container postgres: docker compose exec postgres sh
    10.Acessar banco de dados PostgreSQL: psql -h postgres -U mensageiro -d mensagensdb (senha: secreto123)
    11.Criar table de mensagens: CREATE TABLE mensagens (id SERIAL PRIMARY KEY, conteudo TEXT NOT NULL, criado_em TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
    12.Inserir mensagem: INSERT INTO mensagens (conteudo) VALUES ('Mensagem de teste');
    13.Consultar mensagens: SELECT * FROM mensagens;
    14.Sair do banco de dados PostgreSQL: Ctrl+d
    15.Sair do postgres: Ctrl+d
    
    16.Entrar no container cliente: docker compose exec cliente sh
    17.No cliente, acessar container api: curl http://api:3000
    18.Sair do cliente: Ctrl+d
    
    19.Parar containers: docker compose stop
    20.Remover containers: docker compose rm -f
    21.Remover volume: docker volume rm mateus_volume-dados-postgres
    22.Remover rede: docker network rm mateus_minha-rede
    23.Remover Images: docker rmi node postgres curlimages/curl
    24.Remover arquivo docker-compose.yml: rm docker-compose.yml
    
  3. Criar 2 containers, um servidor com API REST Flask, e um cliente Debian curl para consumir API REST.
    
    1.Criar arquivo de variáveis de ambiente .env:
    HOST_PORT=5000
    
    2.Criar Dockerfile.server:
    FROM python
    WORKDIR /app
    RUN pip3 install flask
    EXPOSE 5000
    
    3.Criar Dockerfile.client:
    FROM debian
    RUN apt update && apt install -y curl
    CMD ["bash"]
    
    4.Criar arquivo docker-compose.yml:
    services:
        server:
            build:
                context: .
                dockerfile: Dockerfile.server
            ports:
                - "${HOST_PORT}:5000"
            restart: unless-stopped
            command: >
                python -c "from flask import Flask,jsonify;app=Flask(__name__);app.route('/api/hello')(lambda: jsonify({'message':'Olá do servidor Flask!'}));app.run(host='0.0.0.0',port=5000)"
            volumes:
                - ./shared:/shared
            working_dir: /shared
    
        client:
            build:
                context: .
                dockerfile: Dockerfile.client
            depends_on:
                - server
            stdin_open: true
            tty: true
            volumes:
                - ./shared:/shared
            working_dir: /shared
    
    5.Acessar API REST no servidor, via cliente: curl server:5000/api/hello
    6.Criar arquivo de teste no cliente: touch teste
    6.Sair do cliente: Ctrl+d
    7.Ver volume shared na máquina host: ls shared/
    8.Acessar API REST no servidor, via máquina host: curl http://localhost:5000/api/hello
    9.Exportar containers: docker compose export -o containers.tar
    10.Importar containers: docker compose import -i containers.tar
    11.Parar e remover containers: docker compose down
    12.Remover Images: docker rmi server client
    13.Remover arquivos: rm Dockerfile.* docker-compose.yml .env
    14.Remover pasta shared: rm -rf shared
    

Elaborado por Mateus Schwede
ubsocial.github.io