<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <docs>https://blogs.law.harvard.edu/tech/rss</docs>
    <title>Docker on FXShell - DevOps &amp; Sec</title>
    <link>https://fxshell.com.br/tags/docker/</link>
    <description>Recent content in Docker on FXShell - DevOps &amp; Sec</description>
    <image>
      <title>Docker on FXShell - DevOps &amp; Sec</title>
      <link>https://fxshell.com.br/tags/docker/</link>
      <url>fxshell.png</url>
    </image>
    <ttl>1440</ttl>
    <generator>Hugo 0.152.2</generator>
    <language>pt-br</language>
    <lastBuildDate>Thu, 14 May 2026 21:17:58 UT</lastBuildDate>
    <atom:link href="https://fxshell.com.br/tags/docker/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Docker</title>
      <link>https://fxshell.com.br/posts/docker/</link>
      <pubDate>Thu, 08 Oct 2020 14:10:44 UT</pubDate>
      <dc:creator>Felipe da Matta</dc:creator>
      <guid>https://fxshell.com.br/posts/docker/</guid>
      <description>Docker é a plataforma de containers mais usada no mercado. Com ela você empacota uma aplicação e todas as suas dependências em uma unidade portátil que roda de forma idêntica em qualquer ambiente — do laptop do dev até a produção em cloud.
O conceito central é isolamento: cada container roda de forma completamente isolada dos demais e do host, usando recursos do próprio kernel Linux.
Dois tipos de isolamento Lógico — Namespaces: isolam processos, redes, usuários e sistemas de arquivos. Cada container enxerga apenas o que é seu.
</description>
      <content:encoded><![CDATA[Docker é a plataforma de containers mais usada no mercado. Com ela você empacota uma aplicação e todas as suas dependências em uma unidade portátil que roda de forma idêntica em qualquer ambiente — do laptop do dev até a produção em cloud.
O conceito central é isolamento: cada container roda de forma completamente isolada dos demais e do host, usando recursos do próprio kernel Linux.
Dois tipos de isolamento Lógico — Namespaces: isolam processos, redes, usuários e sistemas de arquivos. Cada container enxerga apenas o que é seu.
Físico — Cgroups: limitam o uso de CPU, memória e disco. Garantem que um container não consuma recursos dos outros.
Arquitetura O Docker Engine usa três módulos do kernel Linux:
Namespaces — isolamento lógico de processos, redes, usuários Cgroups — isolamento físico de CPU, memória, I/O Netfilter — roteamento de rede, NAT e redirecionamento de pacotes Imagens em camadas: todas as camadas são read-only, exceto a camada superior de cada container (onde as alterações acontecem). Se você tem 5 containers baseados na mesma imagem de 500 MB, o disco não aloca 2,5 GB — todos compartilham a mesma base. Só a camada de escrita de cada container é individual.
Instalação curl -fsSL https://get.docker.com/ | bash docker version docker container ls Para usar sem sudo, adicione seu usuário ao grupo docker:
sudo usermod -aG docker $USER Ciclo de Vida do Container Rodando o primeiro container docker container run hello-world Flags essenciais do run Flag Função -d Daemon — roda em background -ti Terminal interativo (bash, sh) -p 8080:80 Mapeia porta do host para o container -m 128M Limita memória --cpus 0.5 Limita a 50% de um núcleo --name Define nome do container --rm Remove o container ao encerrar Containers interativos # Entrar dentro de um ubuntu docker container run -ti ubuntu # Ver processos (apenas os do container) root@2fd8c26be92e:/# ps -ef UID PID CMD root 1 /bin/bash root 8 ps -ef CTRL+D encerra o container (mata o processo principal). CTRL+P+Q sai sem matar o container.
Containers em background (daemon) Para serviços como nginx, nunca use -ti — o entrypoint não é o bash:
docker container run -d nginx Para executar comandos dentro de um container em execução, use exec:
docker container exec -ti &lt;id&gt; bash docker container exec -ti &lt;id&gt; ls /etc/nginx Gerenciamento docker container ls # containers em execução docker container ls -a # todos (incluindo parados) docker container stop &lt;id&gt; docker container start &lt;id&gt; docker container restart &lt;id&gt; docker container pause &lt;id&gt; docker container unpause &lt;id&gt; docker container rm &lt;id&gt; # remove parado docker container rm -f &lt;id&gt; # força remoção docker container logs -f &lt;id&gt; # logs em tempo real docker container inspect &lt;id&gt; # detalhes completos em JSON docker container stats &lt;id&gt; # uso de CPU/memória em tempo real docker container top &lt;id&gt; # processos rodando no container Limitando Recursos Definir limites na criação:
docker container run -d -m 128M --cpus 0.5 nginx Atualizar em container já em execução:
docker container update --cpus 0.8 --memory 64M &lt;id&gt; Testar pressão com stress (instalar dentro do container):
apt-get install -y stress stress --cpu 1 --vm-bytes 128M --vm 1 Volumes — Persistindo Dados O filesystem do container é volátil — quando o container é removido, tudo dentro dele some. Volumes existem fora do container e persistem independentemente.
Bind Mount — você define o caminho # Montar diretório do host no container docker container run -ti \ --mount type=bind,src=https://fxshell.com.br/opt/meuapp,dst=/app \ debian # Somente leitura docker container run -ti \ --mount type=bind,src=https://fxshell.com.br/opt/meuapp,dst=/app,ro \ debian Docker Volume — gerenciado pelo Docker # Criar volume docker volume create dbdados # Usar volume no container docker container run -d \ --mount type=volume,src=dbdados,dst=/data \ postgres:16 # Listar volumes docker volume ls # Inspecionar docker volume inspect dbdados # Remover (só se não estiver em uso) docker volume rm dbdados # Remover todos os volumes não utilizados docker volume prune Todos os volumes ficam em /var/lib/docker/volumes/.
Compartilhando volume entre containers docker container run -d -p 5432:5432 --name pgsql1 \ --mount type=volume,src=dbdados,dst=/data \ postgres:16 docker container run -d -p 5433:5432 --name pgsql2 \ --mount type=volume,src=dbdados,dst=/data \ postgres:16 Ambos os containers leem e escrevem no mesmo volume.
Backup de volume mkdir /opt/backup docker container run --rm \ --mount type=volume,src=dbdados,dst=/data \ --mount type=bind,src=https://fxshell.com.br/opt/backup,dst=/backup \ debian tar -cvf /backup/bkp-banco.tar /data Dockerfile — Criando Suas Imagens O Dockerfile descreve como construir uma imagem. Cada instrução cria uma nova camada.
Instruções principais Instrução Descrição FROM Imagem base — sempre a primeira linha RUN Executa comando no build, cria camada CMD Comando padrão ao iniciar o container ENTRYPOINT Executável principal do container COPY Copia arquivos para o filesystem ADD Como COPY, mas aceita TAR e URLs ENV Define variáveis de ambiente EXPOSE Documenta a porta que o container escuta VOLUME Declara ponto de montagem de volume WORKDIR Define diretório de trabalho USER Define usuário (padrão: root) LABEL Adiciona metadados à imagem ARG Variável de build-time (não fica na imagem) Exemplo: container com stress FROM debian LABEL app=&#34;stress-test&#34; ENV AMBIENTE=&#34;dev&#34; RUN apt-get update &amp;&amp; apt-get install -y stress &amp;&amp; apt-get clean CMD stress --cpu 1 --vm-bytes 64M --vm 1 docker image build -t meu-stress:1.0 . docker container run -d meu-stress:1.0 Exemplo: Apache com ENTRYPOINT FROM debian RUN apt-get update &amp;&amp; apt-get install -y apache2 &amp;&amp; apt-get clean ENV APACHE_LOCK_DIR=&#34;/var/lock&#34; ENV APACHE_PID_FILE=&#34;/var/run/apache2/apache2.pid&#34; ENV APACHE_RUN_USER=&#34;www-data&#34; ENV APACHE_RUN_GROUP=&#34;www-data&#34; ENV APACHE_LOG_DIR=&#34;/var/log/apache2&#34; LABEL description=&#34;Webserver&#34; version=&#34;1.0.0&#34; VOLUME /var/www/html/ EXPOSE 80 ENTRYPOINT [&#34;/usr/sbin/apachectl&#34;] CMD [&#34;-D&#34;, &#34;FOREGROUND&#34;] Multi-stage build — imagem final mínima Compila em uma imagem pesada, copia apenas o binário para uma imagem leve:
# Stage 1: build FROM golang AS build WORKDIR /src ADD . /src RUN go build -o goapp # Stage 2: imagem final FROM alpine:3.19 WORKDIR /app COPY --from=build /src/goapp /app ENTRYPOINT [&#34;./goapp&#34;] A imagem final tem apenas o binário + Alpine (~5 MB), sem o toolchain Go.
Buildar e publicar # Build local docker image build -t minha-imagem:1.0 . # Ver camadas e histórico docker history minha-imagem:1.0 # Login no Docker Hub docker login # Push docker image tag minha-imagem:1.0 usuario/minha-imagem:1.0 docker push usuario/minha-imagem:1.0 Registry Local Para manter suas imagens em ambiente privado sem depender do Docker Hub:
# Subir um registry local na porta 5000 docker container run -d \ -p 5000:5000 \ --restart=always \ --name registry \ registry:2 # Taguear imagem para o registry local docker tag minha-imagem:1.0 localhost:5000/minha-imagem:1.0 # Push para o registry local docker push localhost:5000/minha-imagem:1.0 Imagens ficam em /var/lib/registry/docker/registry/v2/repositories/.
Docker Swarm — Orquestração em Cluster O Swarm transforma múltiplos hosts Docker em um cluster com load balancing e failover automáticos.
Manager — conhece o estado do cluster, agenda containers, expõe a API.
Worker — executa os containers distribuídos pelo manager.
Criando o cluster # No host manager (gera um token) docker swarm init # Nos hosts workers (usar o token gerado) docker swarm join --token &lt;token&gt; &lt;manager-ip&gt;:2377 # Ver todos os nodes docker node ls Gerenciando nodes # Ver token para adicionar workers docker swarm join-token worker # Ver token para adicionar managers docker swarm join-token manager # Promover worker a manager docker node promote fxshell-02 # Rebaixar manager a worker docker node demote fxshell-02 # Pausar node (não recebe novos containers) docker node update --availability pause fxshell-02 # Dreno para manutenção (migra containers para outros nodes) docker node update --availability drain fxshell-02 # Reativar node docker node update --availability active fxshell-02 # Remover node do cluster docker swarm leave # rodar no próprio node docker node rm fxshell-02 # rodar no manager Services — o coração do Swarm Um Service define quantas réplicas de um container devem rodar, em quais ports e com quais configs. O Swarm distribui as réplicas pelos workers e garante que o número desejado esteja sempre disponível.
# Criar service com 5 réplicas de nginx docker service create \ --name webserver \ --replicas 5 \ -p 8080:80 \ nginx # Listar services docker service ls # Ver em quais nodes estão rodando docker service ps webserver # Detalhes completos docker service inspect webserver # Escalar para 10 réplicas docker service scale webserver=10 # Logs de todos os containers do service docker service logs -f webserver # Remover service docker service rm webserver Service com volume docker service create \ --name webserver \ --replicas 5 \ -p 8080:80 \ --mount type=volume,src=dados,dst=/app \ nginx O volume dados fica disponível em todos os containers do service, em todos os nodes.
Limpeza # Remover containers parados docker container prune # Remover volumes não utilizados docker volume prune # Remover imagens não utilizadas docker image prune # Limpeza completa (containers, imagens, redes, cache de build) docker system prune -a Referência rápida # Containers docker container run -d -p 8080:80 --name web nginx docker container exec -ti &lt;id&gt; bash docker container logs -f &lt;id&gt; docker container stats docker container inspect &lt;id&gt; # Imagens docker image ls docker image pull ubuntu:22.04 docker image build -t app:1.0 . docker image push usuario/app:1.0 docker image rm &lt;id&gt; # Volumes docker volume create dados docker volume ls docker volume inspect dados docker volume rm dados # Swarm docker swarm init docker node ls docker service create --name app --replicas 3 -p 80:80 nginx docker service scale app=5 docker service ps app ]]></content:encoded>
    </item>
    <item>
      <title>Escalabilidade e Conteinerização</title>
      <link>https://fxshell.com.br/posts/escalabilidade-e-conteineriza%C3%A7%C3%A3o-/</link>
      <pubDate>Sat, 09 Mar 2019 16:00:36 UT</pubDate>
      <dc:creator>Felipe da Matta</dc:creator>
      <guid>https://fxshell.com.br/posts/escalabilidade-e-conteineriza%C3%A7%C3%A3o-/</guid>
      <description>Pense em um container como uma espécie de caixinha isolada onde você coloca uma aplicação e tudo que ela precisa para rodar: bibliotecas, dependências, arquivos de configuração e recursos específicos. Essa&quot;caixinha&quot; fica fechada, isolada do ambiente externo, garantindo que a aplicação dentro dela sempre rode da mesma forma, não importa onde ela esteja
Tecnicamente falando, um container é um ambiente isolado no nível do sistema operacional. Diferente das máquinas virtuais (que simulam um computador completo, com sistema operacional e tudo), os containers compartilham o kernel (núcleo) do sistema operacional do host. Isso significa que containers não precisam carregar um sistema inteiro para funcionar — eles reutilizam o que já existe no host, reduzindo drasticamente o uso de recursos.
</description>
      <content:encoded><![CDATA[Pense em um container como uma espécie de caixinha isolada onde você coloca uma aplicação e tudo que ela precisa para rodar: bibliotecas, dependências, arquivos de configuração e recursos específicos. Essa&quot;caixinha&quot; fica fechada, isolada do ambiente externo, garantindo que a aplicação dentro dela sempre rode da mesma forma, não importa onde ela esteja
Tecnicamente falando, um container é um ambiente isolado no nível do sistema operacional. Diferente das máquinas virtuais (que simulam um computador completo, com sistema operacional e tudo), os containers compartilham o kernel (núcleo) do sistema operacional do host. Isso significa que containers não precisam carregar um sistema inteiro para funcionar — eles reutilizam o que já existe no host, reduzindo drasticamente o uso de recursos.
Dois mecanismos principais do kernel Linux tornam isso possível: Namespaces: são responsáveis por criar ambientes isolados. Por exemplo, cada container tem seu próprio espaço para processos, rede, sistema de arquivos e usuários. Isso garante que um container não interfira no outro e que aplicações possam rodar lado a lado, sem conflitos;
Cgroups (ControlGroups): são utilizados pra controlar a quantidade de recursos (memória, CPU, disco) que cada container pode utilizar. Assim, mesmo que um container tente consumir mais recursos que o previsto, ele fica limitado ao que foi definido, garantindo estabilidade ao sistema inteiro.
Isso tudo importa por que? Porque essa combinação permite que você tenha um ambiente padronizado, previsível e extremamente portátil. Uma aplicação empacotada em um container roda exatamente do mesmo jeito na sua máquina, num servidor de teste, em produção ou até mesmo na nuvem. Isso elimina aquele velho problema de “na minha máquina funciona”.
Se você desenvolve uma aplicação web que usa Node.js em uma versão específica, antes você precisava instalar essa versão exata na máquina que rodaria sua aplicação em produção. Com containers, você simplesmente cria uma imagem que já contém exatamente essa versão do Node, as dependências e os arquivos necessários. Ao subir essa imagem num servidor (com Docker, por exemplo), você garante que tudo rode exatamente como você planejou — sem erros surpresa.
Fluxo: Comandos básicos do Docker: Listar containers em execução: docker ps; Listar todos os containers (inclusive parados): docker ps –a; Executar um container a partir de uma imagem: docker run nome-da-imagem. Exemplo: docker run hello-world; Executar um container interativo (com acesso ao terminal): docker run -it nome-da-imagem /bin/bash. Exemplo: docker run -it ubuntu bash; Parar um container em execução: docker stop id-ou-nome-do-container; Iniciar novamente um container parado: docker start id-ou-nome-do-container; Remover um container parado: docker rm id-ou-nome-do-container; Forçar a remoção de um container (mesmo que ainda esteja rodando): docker rm -f id-ou-nome-do-container. Listar imagens disponíveis localmente: docker images; Baixar uma imagem específica do Docker Hub: docker pull nome-da-imagem. Exemplo: docker pull node:20-alpine; Remover uma imagem localmente armazenada: docker rmi nome-ou-id-da-imagem. Visualizar logs de execução do container: docker logs id-ou-nome-do-container; Obter informações detalhadas sobre um container ou imagem: docker inspect id-ou-nome-do-container. Renomear um container: docker rename nome-antigo nome-novo; Executar comandos em containers já em execução: docker exec -it nome-do-container comando. Exemplo: docker exec -it meu-container bash; Copiar arquivos do host para o container: docker cp arquivo host:/caminho-container; Copiar arquivos do container para o host: docker cp container:/caminho-arquivo destino-host. Remover containers parados automaticamente: docker container prune; Remover imagens não utilizadas: docker image prune; Limpar todos os recursos Docker não utilizados: docker system prune. Liberar aplicação para acesso no host: docker run -p 80:80 nginx Dockerfile (FROM, RUN, CMD, COPY, WORKDIR) Se tem uma coisa que você vai escrever muito ao trabalhar com Docker, é o tal do Dockerfile. Ele é só um arquivo de texto, mas com muito poder: é ali que você define o passo a passo para construir a imagem que vai rodar sua aplicação. Funciona como um script declarativo — você diz o que quer que aconteça e o Docker constrói.
O processo é bem linear, e com o tempo você decora a ordem das instruções. Mas no começo, vale entender o papel de cada uma.
FROM Tudo começa com o FROM. É aqui que você escolhe a base da sua imagem. Pode ser o Node, o Python, o Ubuntu ou qualquer outra coisa. O mais comum é usar imagens oficiais que já vêm prontas no Docker Hub.
Exemplo: FROM node:20
Isso quer dizer: “pegue a imagem do Node na versão 20 e comece a construir em cima dela”.
WORKDIR Depois disso, é comum definir um diretório de trabalho com WORKDIR. Isso nada mais é do que dizer: “a partir de agora, tudo que eu fizer vai ser dentro desta pasta aqui”. Isso evita que você tenha que dar comandos com caminhos longos o tempo todo.
Exemplo: WORKDIR /app
COPY Aí vem o COPY, que serve para colocar seus arquivos dentro da imagem. Ele seleciona o que está em sua máquina e joga dentro da imagem que está sendo construída.
Exemplo: COPY . /app
Isso copia tudo o que está no diretório atual para o /app da imagem.
RUN Com os arquivos no lugar, você pode executar comandos com RUN. Ele é muito usado para instalar dependências, criar pastas, mover arquivos, o que for necessário durante a construção da imagem.
Exemplo: RUN npminstall
Esse comando vai rodar dentro da imagem e o resultado fica salvo como uma camada nova.
CMD Por fim, vem o CMD, que define o comando que vai rodar quando o container for iniciado. É como dizer: “quando alguém rodar essa imagem, execute isso aqui por padrão”.
Exemplo: CMD [&ldquo;node&rdquo;, &ldquo;index.js&rdquo;]
Isso vai rodar o index.js usando o Node quando o container subir.
A ordem dessas instruções importa, principalmente porque o Docker guarda o cache de cada etapa. Se você mudar algo no topo do Dockerfile, ele vai reconstruir tudo abaixo. Agora, se você só mexer no CMD, por exemplo, ele reaproveitará o restante.
Com o tempo você vai aprender a montar Dockerfiles mais limpos, diretos e fáceis de manter. Mas comece entendendo bem o básico: que o Dockerfile é onde você escreve a lógica de construção da sua imagem. Sem mágica, sem mistério. Só prática e clareza.
# Etapa 1 - build FROM node:20 AS build WORKDIR /app COPY . . RUN npm install &amp;&amp;npm run build # Etapa 2 - produção FROM node:20-slim WORKDIR /app COPY --from=build /app/dist ./dist CMD [&#34;node&#34;, &#34;dist/index.js&#34;] A primeira etapa instala tudo, roda o build, e a segunda só carrega o resultado. Nada de node_modules, ferramentas de build ou arquivos temporários indo parar na imagem final.
Esse padrão é bem comum em projetos mais maduros, porque ajuda a deixar o deploy mais leve e evita que coisas desnecessárias (ou até perigosas) acabem indo parar em produção.
Se você ainda não usa, comece a testar em projetos pequenos. Depois que você se acostumar, vira um padrão.
Multibuildinds Segurança em containers: resumo Containers e VMs: eles compartilham o kernel com o host, então se houver escape, o risco é grande. Namespaces: isolam recursos como processos, rede, usuários e sistema de arquivos, garantindo que o container veja apenas o que está dentro dele. Capabilities: controlam permissões do processo. O root no container é limitado por padrão. É possível remover (--cap-drop) ou adicionar (--cap-add) capacidades, seguindo o princípio do menor privilégio. Seccomp: funciona como um firewall de syscalls, bloqueando chamadas perigosas. O Docker já traz um perfil padrão, mas é possível criar perfis personalizados. Boas práticas adicionais: não rodar como root, usar imagens mínimas, manter dependências atualizadas e aplicar patches regularmente. Usuários não root e boas práticas de permissões Agora vamos falar de um dos tópicos mais importantes — e muitas vezes ignorado — quando a gente começa a colocar containers em produção: rodar como root ou não. Spoiler: a resposta quase sempre é não.
Por padrão, quando você sobe um container, ele roda como root. E o root dentro do container é praticamente o mesmo root do host. Mesmo que ele esteja tecnicamente isolado, isso é um risco enorme. Se alguém conseguir escapar do container (sim, isso pode acontecer), vai ter acesso privilegiado ao seu sistema. E aí, já era.
A primeira boa prática aqui é criar um usuário não privilegiado dentro da imagem, e forçar o container a rodar com ele. Você pode fazer isso com o comando adduser (ou useradd, dependendo da imagem base) e depois usar USER nomedousuario. E mais: se os arquivos da aplicação forem copiados para o container, o ideal é já definir o dono desses arquivos com &ndash;chown.
FROM node:18-alpine RUN adduser -D appuser USER appuser WORKDIR /app COPY --chown=appuser . . RUN npm ci CMD [&#34;npm&#34;, &#34;start&#34;] Dockerignore e build context Quando você roda um docker build, o Docker precisa saber o que ele vai copiar para o contexto de build — basicamente, tudo que está na pasta onde você roda o comando (ou no caminho que você passar).
Isso é o chamado build context. E é aqui que muita gente se atrapalha.
Por padrão, se você não filtrar nada, o Docker vai tentar mandar tudo que está naquela pasta para o processo de build. Isso inclui .git, node_modules, arquivos grandes, segredos&hellip; tudo mesmo. Isso não só deixa o build mais lento, como também pode vazar dados sensíveis para a imagem final.
É aí que entra o .dockerignore. Ele funciona como um .gitignore, só que para build. Você lista nele o que não deve ser enviado para o build context — simples assim:
.git node_modules .env .vscode *.log Com isso, o Docker ignora essas pastas e arquivos quando empacota o build context. Resultado? Build mais rápido, imagem menor e mais segura.
Aliás, se o seu build estiver demorando demais ou parecendo pesado demais, confira o que está no contexto. Muita gente manda gigas sem saber, só porque esqueceu de ignorar.
Outra boa prática é sempre rodar o docker build o mais perto possível do Dockerfile, e garantir que sua estrutura de pastas esteja organizada. Isso evita surpresas.
Enfim, usar .dockerignore é obrigatório se você quer construir imagens limpas, seguras e eficientes. Não é frescura — é parte do básico bem feito.
Estratégias de cache em builds com npm, pip, etc Se você já rodou um docker build mais de uma vez, talvez tenha notado: às vezes o build voa, às vezes demora uma eternidade. A diferença quase sempre está no cache.
O Docker armazena o resultado de cada instrução do Dockerfile em camadas. Se ele encontrar uma camada idêntica a uma que já construiu antes, ele reaproveita o cache e segue em frente. Só que para isso acontecer, você precisa saber como escrever o Dockerfile do jeito certo.
Ferramentas de análise de imagem: Dive e Snyk Ferramentas para analise de imagem, vale estudar
Volumes e Redes Volumes e persistencia de dados quando container morre.
Volumes Docker: funcionamento interno e drivers Quando falamos em persistência de dados no Docker, inevitavelmente estamos falando de volumes. Eles são a forma oficial, segura e recomendada de manter dados fora do ciclo de vida efêmero dos containers. Mas o que realmente acontece por trás do docker volume create?
Como o Docker gerencia volumes Quando você cria um volume, o Docker registra esse recurso em seu próprio mecanismo de metadados interno. Ele sabe onde o volume está no sistema de arquivos do host, qual driver está usando e qual container está usando aquele volume. Por padrão, esse volume é armazenado em um caminho como:
/var/lib/docker/volumes/[nome_do_volume]/_data Esse _data é aquilo que o container enxerga quando você monta o volume, e o Docker se encarrega de conectar esse diretório ao caminho interno do container que você definiu, como por exemplo /var/lib/mysql.
Se estiver usando uma engine diferente, como containerd ou cri-o, o funcionamento geral segue a mesma lógica, mas o caminho físico pode variar.
O que são drivers de volume O Docker permite usar drivers diferentes para gerenciar onde e como os dados são armazenados. Cada driver implementa uma forma específica de criar, montar e gerenciar volumes. Os mais comuns são:
local (padrão): usa o sistema de arquivos do host. Simples, rápido e suficiente para a maioria dos casos; nfs: permite montar volumes armazenados em servidores NFS, útil para clusters e compartilhamento em rede; tmpfs: armazena tudo na RAM e desaparece ao reiniciar. Serve para dados temporários e testes; drivers de terceiros: como rexray, portworx, que integram com soluções de storage enterprise como EBS, Azure Disk, Ceph, entre outros. Você escolhe o driver no momento da criação:
docker volume create --driver local meu-volume Ou, para um volume NFS:
docker volume create \ --driver local \ --opt type=nfs \ --opt o=addr=192.168.1.100,rw \ --opt device=:/dados/nfs \ volume-nfs Como escolher o driver ideal Depende do seu cenário:
Ambiente de desenvolvimento: use o driver local. É simples e resolve bem; Ambiente de produção com múltiplos hosts:nfs ou outro driver remoto pode ser necessário; Necessidade de performance de leitura/escrita em memória: tmpfs pode ser útil; Ambiente em cloud com orquestrador: drivers especializados como rexray com EBS ou plugins CSI no Kubernetes são boas opções. Comece com o volume local. Ele atende bem na maioria dos cenários. Só parta para opções mais complexas se houver necessidade real de compartilhamento, persistência remota ou requisitos específicos de performance. Volumes: a opção oficial, segura e portável Volumes são gerenciados pelo próprio Docker. Quando você cria um volume com docker volume create, ele é registrado nos metadados internos do Docker e fica salvo, por padrão, em /var/lib/docker/volumes. O que o container enxerga é o diretório _data desse volume.
Pontos fortes:
Isolamento entre containers e o host; Gerenciamento fácil via comandos Docker; Backup e migração mais simples; Recomendado para ambientes de produção. docker run -d --name app \ -v dados-app:/usr/src/app/data \ minha-imagem Bridge: o padrão que funciona para muita coisa Quando você não especifica uma rede, o Docker automaticamente coloca seu container na rede bridge padrão. Essa rede cria um isolamento de rede dentro do host e fornece resolução de nomes entre containers.
Criação e uso de redes personalizadas Uma das grandes vantagens do Docker é poder simular ambientes com vários serviços isolados, mas que ainda assim precisam conversar entre si. E é exatamente aqui que entram as redes personalizadas. Com elas, você tem mais controle, isolamento e previsibilidade. Vamos entender o porquê
Como funciona o DNS interno do Docker Quando você cria uma rede personalizada com docker network create, o Docker automaticamente habilita um serviço de DNS interno para essa rede. Isso significa que cada container que estiver conectado a ela pode ser referenciado pelo seu nome (ou seja, o nome definido na flag &ndash;name).
docker network create minha-rede dockerrun -d --name banco --network minha-rede postgres Nesse caso, a minha-api consegue se conectar ao banco de dados usando o hostname banco, sem precisar de IP fixo, sem um “jeitinho”. O Docker cuida da resolução de nomes.
Como containers se descobrem via hostname Se os containers estão na mesma rede personalizada, o nome de um é visível para o outro. Isso simplifica muito a configuração de aplicações distribuídas.
Por exemplo, uma aplicação Node.js pode se conectar ao MongoDB apenas apontando a URI para mongodb://mongo:27017, assumindo que o container com o Mongo se chama mongo e ambos estão na mesma rede.
Como isolar e expor serviços de forma segura Redes personalizadas são isoladas por padrão. Isso significa que apenas containers conectados à mesma rede conseguem se enxergar. Com isso, você pode:
Isolar bancos de dados, evitando que sejam acessados por containers que não deveriam;
Separar ambientes (ex: dev e prod);
Reduzir a superfície de ataque, limitando o tráfego entre containers.
E caso precise expor um serviço (como um frontend ou API), basta mapear a porta com -p no dockerrun, ou configurar diretamente no Docker Compose.
docker run -d --name frontend --network minha-rede -p 80:3000 minha-app Conectando e desconectando containers dinamicamente Outro ponto importante é que você pode conectar e desconectar containers de redes a qualquer momento:
docker network connect minha-rede containerX docker network disconnect minha-rede containerY Isso permite criar arquiteturas dinâmicas, com controle fino sobre quem fala com quem.
Redes personalizadas não só organizam o tráfego entre seus containers, como também são uma ferramenta fundamental de segurança e isolamento. Entender como elas funcionam e como aproveitar o DNS interno do Docker muda completamente o jeito de estruturar suas aplicações multicontainer. E quando o projeto crescer? A mesma lógica de redes personalizadas será usada em ferramentas como Docker Compose e orquestradores como o Kubernetes.
Segurança com usuários não-root e permissões de arquivos Criar containers seguros vai além de configurar uma imagem funcional. Um dos pilares mais importantes na segurança de ambientes Docker é evitar que containers rodem como root, além de configurar corretamente as permissões de arquivos dentro e fora do container.
Por que evitar o usuário root? Quando um container é iniciado com o usuário root, ele tem permissões totais dentro daquele ambiente isolado. O problema é que, em caso de falha de segurança ou fuga de container (container breakout), esse usuário pode comprometer o host inteiro. A superfície de ataque aumenta consideravelmente.
Boas práticas:
Nunca use root em containers que precisam interagir com dados sensíveis ou que vão rodar em produção;
Prefira rodar com um usuário com permissões mínimas necessárias;
Adicione esse usuário no momento da construção da imagem.
Como criar um usuário não-root na imagem Docker Dentro do Dockerfile, você pode criar um usuário e definir que ele será o usuário padrão do container:
FROM node:18 # Cria o usuário RUN useradd -m appuser # Define permissões para a pasta da aplicação WORKDIR /app COPY . . RUN chown -R appuser:appuser /app # Troca para o usuário USER appuser CMD [&#34;node&#34;, &#34;index.js&#34;] O comando USER muda o usuário efetivo usado durante a execução do container.
Permissões de arquivos e diretórios Mesmo com um usuário não-root, é fundamental garantir que os arquivos e pastas tenham permissões adequadas.
Use chmod e chown corretamente durante o build da imagem;
Garanta que arquivos sensíveis (como tokens, .env, .ssh) estejam protegidos ou fora do contexto do container;
Ao usar volumes, saiba que o usuário do host pode ser diferente do usuário do container — e isso pode gerar problemas de permissão;
Solução comum: mapear o mesmo UID/GID no host e no container, ou usar &ndash;user $(id -u):$(id -g) ao rodar o container.
Evitando escalonamento de privilégio Mesmo com um usuário não-root, containers mal configurados podem ser explorados. Algumas proteções adicionais:
Use readOnlyRootFilesystem (em ambientes orquestrados como Kubernetes);
Não monte o socket do Docker (/var/run/docker.sock) dentro do container;
Use &ndash;cap-drop ALL para remover todas as capabilities Linux e adicione apenas as estritamente necessárias;
Habilite o AppArmor, SELinux ou seccomp no seu host.
Exemplo prático: rodando container com UID/GID definidos docker run \ --rm \ --user $(id -u):$(id -g) \ -v $(pwd):/app \ minha-imagem Esse comando garante que o usuário dentro do container terá os mesmos IDs do usuário do host, evitando problemas de permissão nos volumes montados.
Evitar o uso do root e gerenciar corretamente permissões dentro dos containers são passos cruciais para criar aplicações seguras e prontas para produção. Isso reduz a superfície de ataque e garante que falhas isoladas não se transformem em brechas críticas.
A segurança começa na imagem, passa pelo runtime e se estende até o host. Portanto, cuide de cada camada com atenção!
Para compreender mais sobre o assunto, deixo aqui a sugestão de um ótimo livro:
“Docker: Up &amp; Running” (3ª edição) Autores: Sean P. Kane e Karl Matthias Editora: O&#39;Reilly Media Ano: 2023 Esse livro é um prato cheio para quem já entende os fundamentos e quer dominar recursos como BuildKit, rootless containers, redes avançadas e integração com Kubernetes. Recomendo especialmente os capítulos sobre “Segurança”, “Redes” e “Práticas modernas de build”
Docker Compose: Orquestração de Múltiplos Containers Docker Compose é uma ferramenta que permite definir e executar aplicações multi-container Docker. Com ele, você usa um arquivo YAML para configurar os serviços da sua aplicação, redes e volumes. Depois, com um único comando, você sobe ou derruba todo o ambiente.
Por que usar Docker Compose? Ambientes de desenvolvimento: Facilita a configuração de ambientes complexos com bancos de dados, filas de mensagens, e outros serviços. Testes: Garante que o ambiente de teste seja idêntico ao de produção (ou o mais próximo possível). Aplicações pequenas/médias: Ideal para orquestrar aplicações com alguns serviços sem a complexidade de Kubernetes. Exemplo prático de docker compose no projeto abaixo em nextjs https://github.com/viniciosneves/todo-app-aula-docker
Criado um dockerfile:
FROM node:22 AS builder WORKDIR /app COPY package*.json . RUN npm install COPY . . RUN npm run build FROM node:22-slim WORKDIR /app COPY package*.json . RUN npm install COPY --from=builder /app/dist ./dist EXPOSE 3000 CMD [&#34;node&#34;, &#34;dist/main&#34;] e um dockercompose.yml:
services: postgres: image: postgres:16-alpine restart: unless-stopped ports: - &#34;5432:5432&#34; environment: POSTGRES_DB: ${DB_DATABASE:-todo_db} POSTGRES_USER: ${DB_USERNAME:-postgres} POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres} volumes: - pgdata:/var/lib/postgresql/data networks: - todo-networks app: build: context: . ports: - &#34;3000:3000&#34; environment: DB_HOST: postgres DB_USERNAME: ${DB_USERNAME:-postgres} DB_PASSWORD: ${DB_PASSWORD:-postgres} DB_DATABASE: ${DB_DATABASE:-todo_db} depends_on: - postgres networks: - todo-networks networks: todo-networks: driver: bridge volumes: pgdata: e criado o arquivo .env:
# Database Configuration DB_HOST=postgres DB_PORT=5432 DB_USERNAME=postgres DB_PASSWORD=postgres DB_DATABASE=todo_db # Application PORT=3000 NODE_ENV=development Um outro exemplo abaixo:
Exemplo de docker-compose.yml version: &#39;3.8&#39; services: web: build: . ports: - &#34;80:80&#34; volumes: - .:/app depends_on: - db environment: DATABASE_URL: postgres://user:password@db:5432/mydatabase db: image: postgres:13 environment: POSTGRES_DB: mydatabase POSTGRES_USER: user POSTGRES_PASSWORD: password volumes: - db-data:/var/lib/postgresql/data volumes: db-data: Comandos básicos do Docker Compose: Subir todos os serviços definidos no docker-compose.yml: docker compose up Subir os serviços em segundo plano (detached mode): docker compose up -d Construir ou reconstruir as imagens dos serviços: docker compose build Parar os serviços e remover os containers: docker compose down Parar os serviços, mas manter os containers: docker compose stop Listar os serviços em execução: docker compose ps Visualizar os logs de todos os serviços (ou de um específico): docker compose logs [nome-do-servico] Executar um comando em um serviço: docker compose exec [nome-do-servico] [comando] Uso de .dockerignore: economize tempo e evite vazamentos Se você está usando Docker para empacotar aplicações, precisa conhecer o.dockerignore. Ele funciona de forma parecida com o .gitignore, e serve para excluir arquivos e pastas do contexto de build da imagem. Parece simples, mas isso impacta diretamente na performance do build, na segurança da imagem gerada e também naprevenção de bugs difíceis de rastrear.
Por que ele é importante? Toda vez que você roda um docker build, o Docker precisa copiar o contexto de build (ou seja, todos os arquivos e pastas do diretório atual) para dentro do processo de build, e isso inclui coisas que você não deveria mandar para dentro da imagem: arquivos de configuração locais, dependências, secretkeys, diretórios de cache, e por aí vai.
Sem um .dockerignore bem configurado, você pode:
Subir acidentalmente arquivos sensíveis (como .env, id_rsa, .git/config); Enviar megabytes (ou gigabytes) de arquivos desnecessários para o build; Quebrar a camada de cache, fazendo builds demorarem mais do que o necessário. Exemplo prático
Imagine que seu projeto tem a seguinte estrutura:
meu-app/ ├── node_modules/ ├── .env ├── .git/ ├── build/ ├── src/ ├── Dockerfile ├── docker-compose.yml Um bom .dockerignore seria:
node_modules .env .git build *.log Esse simples arquivo já previne:
Que você mande milhares de arquivos do node_modules para o interior da imagem;
Que o .env vá para dentro do container em produção;
Que a pasta .git com histórico e metadados seja copiada inutilmente;
Que arquivos de build anteriores entrem por engano na nova imagem.
Dica extra Se você usa o GitHub Copilot ou outros assistentes de código, sempre revise se o .dockerignore sugerido cobre os arquivos do seu projeto. Cada stack tem necessidades diferentes e um bom .dockerignore deve ser escrito com carinho pra sua realidade.
Ah, e uma boa prática: mantenha seu .dockerignore próximo do seu Dockerfile, na raiz do projeto. Assim fica mais fácil de entender o que está sendo levado para dentro da imagem e o que fica fora.
Logs estruturados e centralização com Loki, Fluentd e Promtail Quando se trabalha com containers, especialmente em ambientes mais robustos e com múltiplas instâncias, confiar apenas no docker logs deixa de ser suficiente. Isso porque os logs ficam fragmentados entre vários containers e, caso um container seja destruído, os logs geralmente se perdem. A solução? Centralizar tudo e garantir que os logs sejam estruturados.
Logs estruturados nada mais são do que registros em formato padronizado (geralmente JSON), onde cada entrada tem campos consistentes como timestamp, level, message, service, entre outros. Isso facilita não só a leitura, mas principalmente a busca e a correlação de eventos.
E é aqui que entram ferramentas como o Loki, o Fluentd e o Promtail:
Promtail é um agente que roda junto dos seus containers, lê os logs locais e os envia para o Loki;Loki é o sistema de back-end, desenvolvido pela Grafana Labs, especializado em armazenar logs de forma eficiente, com um modelo similar ao Prometheus (mas para logs); Fluentd é uma alternativa poderosa para coleta, processamento e roteamento de logs. Ele pode substituir o Promtail em cenários mais complexos, com necessidade de transformar ou enriquecer os logs antes do envio. A grande vantagem desse trio é a capacidade de coletar logs de múltiplos containers, normalizá-los e enviá-los para uma interface como o Grafana, onde você pode fazer queries detalhadas, montar dashboards e correlacionar eventos com métricas. Se você está começando agora, vale montar um setup simples com Docker Compose que inclua Promtail, Loki e Grafana. Além de ser uma ótima experiência prática, você vai entender o valor de logs estruturados de verdade.
Docker Events: monitore em tempo real o que acontece nos containers Saber o que está rolando em tempo real dentro do seu ambiente Docker pode ser a diferença entre detectar um problema antes que ele escale ou passar horas tentando descobrir o que aconteceu. O comando dockerevents é uma ferramenta nativa, leve e extremamente útil para acompanhar as mudanças de estado dos containers, imagens, volumes e outros objetos Docker.
Com ele, você pode visualizar eventos como criação, inicialização, parada, remoção, attach, kill e até falhas de rede ou reinicializações. Tudo isso com timestamps e informações precisas.
Por exemplo, se você quiser monitorar os eventos de todos os containers:
Se quiser filtrar por container específico:
docker events --filter container=meu-container Ou ainda, se quiser acompanhar apenas eventos de tipo específico (por exemplo, apenas eventos de tipo container):
dockerevents --filtertype=container Diagnóstico com dockerinspect: lendo metadados como um(a) detetive Se você já usou o dockerinspect, provavelmente foi para buscar um IP ou o path de um volume. Mas, o que pouca gente explora, é o poder de investigação que esse comando oferece para diagnósticos mais profundos e bem informados.
O dockerinspect devolve uma saída JSON detalhada sobre containers, imagens, volumes, redes&hellip; praticamente qualquer recurso do Docker. Com ele, é possível saber:
/ Qual comando original está sendo executado no container (Config.Cmd), se o container está utilizando um volume e onde ele está montado (Mounts); / Quais portas estão expostas e mapeadas (NetworkSettings.Ports); / Qual é a imagem base (Image); Se o container está sendo reiniciado frequentemente ou se está parado por erro (State); Quer saber se o container está morrendo por falta de memória? Verifique State.OOMKilled. Quer automatizar uma checagem? Use o &ndash;format para filtrar exatamente o que precisa:
dockerinspect --format=&#39;{{.State.Status}}&#39; meu_container Esse comando vai te devolver apenas o status atual, como running ou exited, sem poluir o seu terminal. E mais, combinar dockerinspect com ferramentas como jq ou usar em scripts de shell pode turbinar suas rotinas de troubleshooting.
Prático, poderoso e já incluído na sua instalação do Docker. Da próxima vez que algo der errado, não chute — inspecione!
Checklist de produção: o que revisar antes de subir o seu container Antes de colocar qualquer container em produção, vale a pena fazer uma última checagem. A ideia aqui não é só garantir que o container roda, mas sim que ele está pronto para um ambiente real: seguro, leve, monitorável e resiliente. Esse checklist é uma espécie de guia prático para ajudar nesse momento decisivo.
Imagem otimizada
Evite usar imagens genéricas e pesadas, como node:latest. Prefira versões slim ou crie uma imagem multistage para garantir que apenas o essencial vá para produção;
Variáveis de ambiente seguros
Verifique se as variáveis sensíveis (como senhas e tokens) estão sendo passadas via secrets: e não expostas via env_file ou diretamente no Compose;
Limites de recursos definidos
Defina limites claros de CPU e memória para evitar que o container sobrecarregue o host:
deploy: resources: limits: cpus: &#39;0.50&#39; memory: 512M Healthcheck configurado
Um bom healthcheck ajuda o orquestrador a saber quando reiniciar o container. Ele também serve como alerta para instabilidades:
healthcheck: test: [&#34;CMD&#34;, &#34;curl&#34;, &#34;-f&#34;, &#34;http://localhost:3000/health&#34;] interval: 30s timeout: 10s retries: 3 Log estruturado
Certifique-se de que o app gera logs no formato JSON (ou outro formato estruturado) e que eles estão sendo enviados para uma stack de observabilidade (ex.: Fluentd, Loki, Promtail);
Log estruturado
Certifique-se de que o app gera logs no formato JSON (ou outro formato estruturado) e que eles estão sendo enviados para uma stack de observabilidade (ex.: Fluentd, Loki, Promtail);
USER node Network isolada
Use redes específicas para comunicação entre serviços, evitando o uso da bridge padrão. Isso aumenta a segurança e o controle;
Persistência de dados garantida
Volumes bem configurados para garantir que nenhum dado importante será perdido após um restart;
Labels e metadados
Inclua labels no Compose para facilitar a automação e a integração com ferramentas de observabilidade e monitoramento:
labels: com.example.service: &#34;minha-api&#34; Teste final local
Simule o ambiente de produção localmente usando docker-compose -f docker-compose.yml -f docker-compose.prod.ymlup. Se estiver tudo certo, então pode subir com confiança.
Esse checklist não é só um ritual — é uma defesa contra surpresas desagradáveis. Com ele, você transforma seu container de algo que &ldquo;funciona na minha máquina&rdquo; para algo que roda bem, de forma previsível e segura, em produção.
LIVRO: “Como se faz DevOps: Organizando pessoas, dos silos aos times de plataforma” Autores: Leonardo Leite, Paulo Meirelles, Fabio Kon Editora: Novatec Ano: 2024 Para quem quer entender o DevOps além das ferramentas, este livro traz uma abordagem prática e crítica sobre como times reais se organizam para entregar software com qualidade e colaboração. Leia especialmente a Parte 2, que discute diferentes formas de estruturar equipes — desde departamentos isolados até modelos mediados por APIs — e como isso impacta a cultura, a eficiência e o alinhamento entre desenvolvimento e operações. ]]></content:encoded>
    </item>
    <item>
      <title>Microservices Async Demo</title>
      <link>https://fxshell.com.br/posts/microservices-async-demo/</link>
      <pubDate>Sat, 09 Mar 2019 16:00:36 UT</pubDate>
      <dc:creator>Felipe da Matta</dc:creator>
      <guid>https://fxshell.com.br/posts/microservices-async-demo/</guid>
      <description>Este projeto demonstra uma arquitetura de microsserviços com comunicação assíncrona utilizando RabbitMQ. O objetivo é aplicar os conceitos de desacoplamento, escalabilidade e mensageria aprendidos na disciplina.
Tecnologias utilizadas Node.js com Express RabbitMQ (mensageria) Docker e Docker Compose cURL para testes de API Estrutura do Projeto microservices-async-demo/ │ ├── docker-compose.yml ├── README.md │ ├── service-order/ │ ├── Dockerfile │ ├── package.json │ ├── wait-for-rabbit.sh │ └── src/ │ └── index.js │ ├── service-payment/ │ ├── Dockerfile │ ├── package.json │ ├── wait-for-rabbit.sh │ └── src/ │ └── index.js Microsserviços ServiceOrder: responsável por criar e listar pedidos (POST /orders, GET /orders). ServicePayment: responsável por processar pagamentos dos pedidos. Fluxo Assíncrono O cliente cria um pedido via ServiceOrder. O ServiceOrder publica uma mensagem no RabbitMQ. O ServicePayment consome a mensagem e processa o pagamento. sequenceDiagram participant Cliente participant ServiceOrder participant RabbitMQ participant ServicePayment Cliente-&gt;&gt;ServiceOrder: POST /orders ServiceOrder-&gt;&gt;RabbitMQ: Publica pedido na fila RabbitMQ-&gt;&gt;ServicePayment: Entrega mensagem ServicePayment-&gt;&gt;ServicePayment: Processa pagamento Como Executar Clonar o repositório: git clone https://github.com/fxshelll/microservices-async-demo.git Subir os serviços: docker compose up --build Acessar o RabbitMQ
</description>
      <content:encoded><![CDATA[Este projeto demonstra uma arquitetura de microsserviços com comunicação assíncrona utilizando RabbitMQ. O objetivo é aplicar os conceitos de desacoplamento, escalabilidade e mensageria aprendidos na disciplina.
Tecnologias utilizadas Node.js com Express RabbitMQ (mensageria) Docker e Docker Compose cURL para testes de API Estrutura do Projeto microservices-async-demo/ │ ├── docker-compose.yml ├── README.md │ ├── service-order/ │ ├── Dockerfile │ ├── package.json │ ├── wait-for-rabbit.sh │ └── src/ │ └── index.js │ ├── service-payment/ │ ├── Dockerfile │ ├── package.json │ ├── wait-for-rabbit.sh │ └── src/ │ └── index.js Microsserviços ServiceOrder: responsável por criar e listar pedidos (POST /orders, GET /orders). ServicePayment: responsável por processar pagamentos dos pedidos. Fluxo Assíncrono O cliente cria um pedido via ServiceOrder. O ServiceOrder publica uma mensagem no RabbitMQ. O ServicePayment consome a mensagem e processa o pagamento. sequenceDiagram participant Cliente participant ServiceOrder participant RabbitMQ participant ServicePayment Cliente-&gt;&gt;ServiceOrder: POST /orders ServiceOrder-&gt;&gt;RabbitMQ: Publica pedido na fila RabbitMQ-&gt;&gt;ServicePayment: Entrega mensagem ServicePayment-&gt;&gt;ServicePayment: Processa pagamento Como Executar Clonar o repositório: git clone https://github.com/fxshelll/microservices-async-demo.git Subir os serviços: docker compose up --build Acessar o RabbitMQ
Painel: http://localhost:15672
Usuário: guest
Senha: guest
Testes com cURL curl -X POST http://localhost:3001/orders \ -H &#34;Content-Type: application/json&#34; \ -d &#39;{&#34;id&#34;: 1, &#34;item&#34;: &#34;Curso Microsserviços&#34;, &#34;valor&#34;: 149.90}&#39; Listar pedidos curl http://localhost:3001/orders Listar pagamentos curl http://localhost:3002/payments Considerações Os serviços aguardam o RabbitMQ estar pronto antes de iniciar. A fila utilizada é chamada orders. Os pagamentos são simulados com delay e registrados com timestamp. ]]></content:encoded>
    </item>
  </channel>
</rss>
