Alpine – Faça você mesmo

Oi Pessoal,

O MundoDocker trás hoje para você um pequeno tutorial de como é possível criar uma imagem enxuta, somente com o que você precisa e utilizando menos espaço possível. Para isso será necessário utilizar uma das duas imagens mais limpas do Docker, são elas: Alpine ou BusyBox, nesse tutorial vamos focar na Alpine, uma das mais buscadas atualmente.

Para que não conhece, a Alpine é uma distribuição construída com musl libc e BusyBox, que é conhecida como canivete suíço, pois combina versões minúsculas de muitos utilitários comuns no UNIX em um único pequeno executável. Algumas características de Alpine:

Pequena

Enquanto a menor imagem para Docker precisa de cerca de 130MB de espaço em disco, a Alpine precisa de no máximo 8MB, isso faz com que, mesmo você montando todo o seu ambiente, ele nunca terá o mesmo tamanho do que se montando em um imagem tradicional, isso é ótimo, pois deixa o ambiente ainda mais enxuto e simples de migrar.

Simples

Você tem apenas aquilo que é necessário para o funcionamento de sua aplicação, se precisar de mais alguma biblioteca, é só instalar, você não precisa se preocupar em desativar ou remover lixos, eles simplesmente não existem.

Segura

Alpine foi desenvolvida pensando em segurança, e para garantir isso os desenvolvedores se preocuparam aprimorar os recursos de segurança do kernel como grsecurity/PaX, além disso, todos os binários foram compilados em executáveis independente de posição, isso previne alguns uso problemas relacionados a buffer overflow e outros tipos de ataques envolvendo estouro de pilha.

Mãos a obra?

Nosso exemplo consistirá em montarmos uma imagem de com Alpine e Nodejs, e vamos comparar o tamanho da nova imagem que montamos com Alpine e outras distros disponíveis.

A Aplicação:

Será algo bem simples, apenas uma aplicação olá mundo:

var http = require('http');
http.createServer(function(req,res) {
 res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });
 res.end('Exemplo Node.js Mundo Docker!');
}).listen(8080);

Colocamos o nome de app.js, não esqueça de criar o package.json com as dependências da aplicação:

{
"name": "docker_web_app",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "First Last <[email protected]>",
"main": "app.js"
}

Agora criamos nosso Dockerfile:

FROM alpine:3.1
# Update
RUN apk add --update nodejs
# Cria a pasta da app
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Instala as dependencias da app
COPY package.json /usr/src/app/
RUN npm install
# copia a app
COPY . /usr/src/app
EXPOSE 8080
CMD ["node", "/usr/src/app/app.js"]

 

Não é nada muito complexo, basta você informar qual imagem base utilizará, e a diferença está no instalador de dependências, que para o Alpine é o apk. Agora vamos gerar a imagem:

docker build -t alpineteste .

Será gerado uma nova imagem com o nome de alpineteste, agora vamos comparar o tamanho dessa imagem com outras:

Alpine

Lembrando, que utilizamos a imagem base de cada distribuição e em cima dela instalamos o node e subimos essa aplicação, note que a diferença é exorbitante, isso por que a Alpine tem apenas o que é necessário para essa aplicação rodar, nada além disso.

Como podem ver, utilizando essa abordagem seu ambiente fica ainda mais escalável, e claro ainda mais portável, pois quanto menos a sua imagem, melhor é para transitar ela entre os hosts (não é necessário baixar megas e megas da imagem no primeiro deploy por exemplo) .

Gostou? nos ajude divulgando o Blog 😉

Grande abraço!