Seu próprio servidor web em contêiner

docker_tudo

Criando um servidor web utilizando o Lighttpd dentro de um contêiner do Docker em alguns poucos passos.

Instalando o Docker

Quem está no Ubuntu:

$ sudo apt-get install docker

No caso da Debian o Docker está (1) disponível por padrão somente para unstable e testing; para instalá-lo lo stable (Jessie) acrescente o repositório jessie-backports nas fontes do APT e como (2) já existia um pacote com este mesmo nome ele é chamado de docker.io (mas nada que um alias em .profile não resolva).

Na documentação do Docker podem ser encontrados os procedimentos para instalação em CentOS, Fedora, RHEL, demais distribuições de Linux e sistemas operacionais.

Não se esqueça de colocar seu próprio usuário dentro do grupo ‘docker’, assim não é necessário ficar prefixando os comandos com ‘sudo’ a todo instante.

Criando um Dockerfile

Na verdade precisamos criar algumas coisas antes, digite:

$ cd
$ mkdir -p ~/lighttpd/html
$ cd lighttpd

Dentro de “~/lighttpd/” crie um script chamado runserver com o seguinte conteúdo:

#/bin/sh
$( which lighttpd ) -D -f /etc/lighttpd/lighttpd.conf

Não se esqueça de deixá-lo com atributo de execução! Este programa serve para rodar o Lighttpd em modo dæmoníaco! 😈

Agora crie o arquivo Dockerfile com o seguinte conteúdo:

FROM ubuntu:latest
RUN apt-get update && apt-get install --yes lighttpd
COPY runserver /runserver
EXPOSE 80
WORKDIR "/"
CMD "/runserver"

O que isto faz? A primeira coisa é dizer ao Docker para utilizar — FROM — a última versão da imagem do Ubuntu e executar — RUN — e instalar o Lighttpd do repositório (como a base vem fazia eu preciso rodar um update antes), copiar — COPY — o script de inicialização para o diretório raiz da imagem, indicar — EXPOSE — que a porta 80 deverá ficar visível no contêiner, configurar o diretório de trabalho — WORKDIR — como o raiz mesmo e, finalmente, indicar que é para executar — CMD — o script que executa o Lighttpd quando o contêiner for executado.

E por que usar o Dockerfile? Não poderia ser feito diretamente dentro do contêiner em execução? Sim mas entenda o Dockfile como um arquivo de configuração do contêiner, ele guarda a história do que é preciso ser feito e, a partir dele, rapidamente possível refazê-lo sempre que necessário.

Criando a imagem

Agora vem a parte divertida, a montagem da imagem para o contêiner. Dentro do diretório “~/ligthttp/” execute:

$ docker build --tag=lighttpd:latest .

E espere os respectivos downloads (sim, ele baixará a imagem do Ubuntu) e ao finalizar retornará algo como “Successfully built «xxxxxxxxxxxx»”, sendo esta sequência um número hexadecimal de 48-bit que é o ID da imagem gerada.

Preparando o que falta

Enquanto os arquivos são baixados, e dentro de “~lighttpd/www/”, crie o “index.html”:

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
 </head>
 <body style='background-color:#f1c594'>
  <h1>Olá mundo!</h1>
  <p>Parabéns, o contêiner está funcionando!</p>
 </body>
</html>

É assim mesmo, bem simples para  justamente se ter o que testar.

Iniciando o contêiner

Hora de colocar o contêiner para funcionar, digite:

$ docker run --publish 8000:80 --volume=${HOME}/lighttpd/html:/var/www/ --detach=true lighttpd:latest

Uma pausa para explicando esta extensa linha:

  • –publish 8000:80 : Faz o Docker redirecionar a porta TCP 8000 para a porta 80 do contêiner;
  • –volume= … :/var/www” : Monta o diretório “~/lighttpd/html/” seja “montado” em “/var/www/” do contêiner;
  • –detach=true : Indica que para liberar o console após a execução e
  • lighttpd:latest : É o nome da imagem que será utilizada como base.

Agora abra um navegador web qualquer e acesse 127.0.0.1:8000 (ou localhost:8000):

docker-1_ola_mundo

E pronto, um servidor web utilizando o Lighttpd funcionando! Experimente alterar a cor de fundo do <BODY> no arquivo “index.html” e atualizar a página para ver o que acontece.

Salve a linha utilizada para iniciar o contêiner em um script de nome “run” em “~/lighttpd”:

#!/bin/sh
docker run \
     --publish 8000:80 \
     --volume=${HOME}/docker/lighttpd/html:/var/www/ \
     --detach=true \
       lighttpd:latest

Isto é só para guardar a memória do comando e assim não ficar procurando por ela no histórico em caso de necessidade.

Algumas dicas sobre o Docker

Acrescentando algumas informações úteis.

Use “docker ps” para ver os contêineres que estão em execução:

$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                  NAMES
0987283d55c3        lighttpd:latest     "\"/bin/sh -c \"/run   48 minutes ago      Up 29 minutes       0.0.0.0:8000->80/tcp   agitated_mestorf

Preste atenção ao número hexadecimal de 12 dígitos, ele identifica o contêiner e será parâmetro obrigatório nos comandos.

O ID do meu contêiner é 0987283d55c3 mas ele também pode ser referenciado como agitated_mestorf — o Docker cria estes nomes divertidos que funcionam como apelidos — e é possível usar a tecla «TAB» para ajudar a completá-los.

Querendo saber o status do contêiner:

$ docker stats 0987283d55c3
CONTAINER           CPU %               MEM USAGE/LIMIT      MEM %               NET I/O
0987283d55c3        0.00%               1.051 MiB/3.76 GiB   0.03%               2.159 KiB/648 B

Pressione «CTRL»+«C» para sair.

Desejando ver quais processos estão em execução no contêiner:

$ docker top 0987283d55c3
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                32082               4840                0                   11:33               ?                   00:00:00            /bin/sh -c "/runserver"
root                32119               32082               0                   11:33               ?                   00:00:00            /bin/sh /runserver
www-data            32121               32119               0                   11:33               ?                   00:00:00            /usr/sbin/lighttpd -D -f /etc/lighttpd/lighttpd.conf

Precisando interromper o contêiner:

$ docker stop 0987283d55c3
0987283d55c3

Necessitando iniciar o contêiner:

$ docker start 0987283d55c3
0987283d55c3

Mas e quanto aquele script “run”? Não é para utilizá-lo? Na verdade não, ele serve para criar um novo contêiner com as mesmas características e configurações a partir da imagem criada como “lighttpd:latest”, ou seja, ao executá-lo volta-se ao ponto de partida.

Contêineres são bem diferentes de máquinas virtuais clássicas, mas tenha em mente que uma imagem é como o “/usr/bin/mc” enquanto que que o o contêiner é o Midnight Commander sendo executado e você pode executar quantos “mc” desejar a partir do binário, correto? Pense em um contêiner como um programa que podemos alterar pausar e retornar a ele conforme nossa necessidade.

Se não lembra direito qual é/era ID do contêiner ou para ter uma lista de todos os contêineres use:

$ docker ps --all
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                           PORTS                  NAMES
0987283d55c3        lighttpd:latest     "\"/bin/sh -c \"/run   About an hour ago   Up 9 minutes                     0.0.0.0:8000->80/tcp   agitated_mestorf
626a5d8181af        lighttpd:latest     "\"/bin/sh -c \"/run   About an hour ago   Exited (137) About an hour ago                          ecstatic_galileo
19f85285d6ae        lighttpd:latest     "\"/bin/sh -c \"/run   About an hour ago   Exited (137) About an hour ago                          goofy_shockley

E para remover um contêiner do disco use:

$ docker rm 626a5d8181af

Finalizando

Consulte o Docker Cheat Sheet para ter uma noção dos outros comandos que podem ser utilizados e sua sintaxe. E até a próxima!

Atualização:
Procurando algo que possa rodar os contêiners do Docker em MacOS X ou Windows?

Anúncios

5 comentários sobre “Seu próprio servidor web em contêiner

  1. Pingback: Seu próprio servidor web lighttpd em contêiner Docker - Peguei do

  2. Pingback: Experimentando o Juju | giovannireisnunes

  3. Pingback: Revendo o “olá (mundo) de 1959” | giovannireisnunes

  4. Pingback: Contêineres com LXC – parte 1 | giovannireisnunes

  5. Pingback: Primeiros passos em AWS e AWS CLI | giovannireisnunes

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s