docker-capa-post-parte-3.png

Neste artigo, vamos rodar um contêiner Docker a partir de uma imagem do Docker Hub e acessar via navegador.

Observação: Este é o terceiro artigo de uma trilha chamada “Docker”. Fica o convite de conhecer os demais artigos!

No artigos anteriores, vimos os conceitos do docker e como criar e executar um contêiner. Bacana, mas como elevamos mais um pouquinho o nível? Neste artigo iremos entender a definição de parametrizarmos as portas do contêiner, ou seja, tornar ele acessível “para fora”. E também iremos mapear uma pasta de nosso host para o contêiner, substituindo a página welcome do nosso servidor web de teste. Para isso, viremos utilizar o nginx. Em breve teremos aqui um artigo para explorarmos mais esta poderosa ferramenta.

NGINX, pronunciado “engine-ex,” é um famoso software de código aberto para servidores web lançado originalmente para navegação HTTP. Hoje, porém, ele também funciona como proxy reverso, balanceador de carga HTTP e proxy de email para os protocolos IMAP, POP3, e SMTP. O NGINX foi lançado em Outubro de 2004.

Inicialmente, vamos garantir que não temos nenhuma imagem e nenhum contêiner em nosso docker, para tal, vamos executar os comandos a seguir:

# Para listar todos os contêiners
$ docker container ps -a
# Para listar toas as imagens
$ docker images

Teremos uma listagem vazia, tanto de imagens como de contêiners, semelhante a imagem abaixo:

images-containers.png

Este arquivo é escrito em uma estação com sistema operacional Windows. Para as demonstrações, estou utilizando o console do ubuntu instalado nesta estação com o wsl2.

O Subsistema do Windows para Linux (WSL) é um recurso do Windows que permite executar um ambiente Linux em seu computador Windows, sem a necessidade de uma máquina virtual separada ou inicialização dupla. O WSL foi projetado para fornecer uma experiência perfeita e produtiva para desenvolvedores que desejam usar o Windows e o Linux ao mesmo tempo.

Caso não conheça o wsl, você pode conferir sobre neste link. Caso não tenha o wsl instalado em sua estação e gostaria de instalá-lo, você pode acessar este link.

Agora, vamos criar nosso peiro webservice utilizando a imagem do nginx executando o comando abaixo:

$ docker container run --name webservice1 -p 8080:80 -d nginx

Vamos entender o comando:

  • docker: É o executor do comando
  • container: Indica que o comando irá atuar em um contêiner
  • run: É a porta de entrada do docker e irá realizar 4 (quatro) operações:
    1. Baixa a imagem (se não encontrada localmente) $ docker image pull
    2. Cria o contêiner docker container create
    3. Inicializa o contêiner docker container start
    4. Uso do modo interativo e executa o comando docker container execute
  • --name: Nome dado ao contêiner. Neste caso webservice1
  • -p: Define a porta exposta ‘para fora’ do contêiner e a porta ‘interna ao’ contêiner. Neste caso 8080 a porta que acessaremos ao realizar uma requisição HTTP e 80 a porta interna ao contêiner, padrão do nginx.
  • -d: Realiza a liberação do console e executa a tarefa em segundo plano. Desta forma teremos o console liberado para serguirmos com nosso estudo.
  • nginx: Imagem utilizada que será baixada no Docker Hub.

Como vimos no artigo anterior, o comando irá baixar a imagem (pois já verificamos que não temos nenhuma imagem) e executar um contêiner com a nossa parametrização. Teremos um resultado semelhante a este:

create-webservice1.png

Para validarmos a execução com êxito do nginx em nossa estação, basta abrir um navegador e acessar a porta 8080 de seu localhost. O endereço será http://localhost:8080/. E teremos a apresentação da página home do nginx.

nginx-home.png

E para podermos ver o direcionamento de porta, vamos listar todos os contêiners ativos:

$ docker container ps

direcionamento-porta.png

Note a coluna PORTS. Ela possui a informação 0.0.0.0:8080 -> 80/tcp. Nesta coluna é apresentada o direcionamento para a porta externa ao contêiner 8080 e a porta 80 para dentro do contêiner.

Bacana, liberamos o console para serguirmos os estudos, mas como está a execução do nosso contêiner? De forma rápida, podemos acessar os últimos logs gerados por ele digitando o comando abaixo. Desta forma podemos até visualizar a requisição de nosso navegador na porta 8080.

$ docker container logs webservice1

conteiner-logs.png

O que pode acontecer se iniciarmos um novo contêiner nginx (ou até mesmo com outra imagem) apontando para a mesma porta 8080?

Vamos executar o comando para visualizarmos que o webservice1 segue em execução e em seguida o comando para criarmos o webservice2 e também apontar para a porta 8080.

# Listar containers ativos
$ docker container ps
# Criação do webservice2
$ docker container run --name webservice2 -p 8080:80 -d nginx

container-erro-porta.png

Podemos perceber na imagem que o hash de criação do contêiner foi criado, mas no momento de sua execução foi apresentado o erro de que a porta 8080 já estava alocada para outro contêiner.

Executando o comando abaixo, poderemos entender melhor o que aconteceu.

$ docker container ps -a

Conferindo a lista de contêiners criados, teremos um webservice1 em execução e o webservice2 criado, mas sem o direcionamento das portas.

ws2-semporta.png

Agora vamos parar o container webservice1 e tentarmos criar o webservice3 apontando para a mesma porta.

# Parar o container webservice1
$ docker container stop webservice1
# Criação do webservice2
$ docker container run --name webservice3 -p 8080:80 -d nginx
# Listar conteiners ativos
$ docker container ps

Como podemos perceber, a criação de um contêiner apontando para uma porta não pode ser realizada quando o mesmo estiver ativo, mas ao criarmos o webservice3 com o webservice1 parado, vimos que o contêiner roda com êxito. Mas ao tentar voltar a executar o webservice1 com o comando abaixo, podemos ver que não será possível.

Abaixo temos a imagem mostrando justamente os passos: docker container ps -a mostrando que temos o webservice1 parado e o webservice2criado e não iniciado, pois houve o conflito de portas no momento de sua execução. Após temos a criação do webservice3 com êxito e o hash informando seu início. No comando seguinte temos a listagem de todos os contêiners demonstrando que o webservice3 está em execução. E por fim temos a tentativa de iniciar o contêiner webservice1, mas sem sucesso, por termos o conflito de porta.

E por fim, vamos criar o webservice4, mas dessta vez ele irá ser acessado a partir da porta 8081. Neste caso não teremos problemas de conflito e o nginx irá executar com êxito, por se tratar da disponibilização de outra porta. E se tratando de contêiners, não é um problema webservice1 e webservice4 escutarem a mesma porta, justamente por se tratar de máquinas diferentes. abaixo temos o comando para a criação do webservice4 e a listagem de contêiners que estão ativos.

# Parar criar o webservice4
$ docker container run --name webservice4 -p 8081:80 -d nginx
# Listar conteiners ativos
$ docker container ps

ws4.png

E agora temos o resultado dos navegadores: Um acessando o contêiner webservice3 através da porta 8080 e o outro navegador acessando o webservice4 através da porta 8081.

2ws.png

Agora vamos substituir a página index.html do nginx, a página que podemos ver nas imagens acima. Vamos mapear uma pasta do nosso host para o contênier justamente com a nossa página index.html. No prompt de comando (no nosso caso o ubuntu), vamos criar uma página chamada html. O comando linux para criar o diretório e depois acessar o mesmo está domonstrado abaixo:

# Para criar o diretório
$ mkdir html
# Para acessar o diretório
$ cd html

dir-html.png

Vamos abrir o vscode em nossa estação para criarmos o nosso arquivo html com o comando code . . Caso não tenha o visual studio code instalado, crie o arquivo em seu editor de preferência e salve o mesmo dentro do diretório html criado. O conteúdo do html está abaixo. Salve o arquivo como index.html.

<html>
  <head>
    <title>Docker Parte 3</title>
  </head>
  <body>
    <h1>Nova home do nginx</h1>
  </body>
</html>

Ao salvar o arquivo, certifique-se que o mesmo está na pasta html que criamos.

Iremos estudar mais a frente a utilização de volumes, mas para este pequeno cenário, vamos mapear uma pasta de nosso host para nosso contêiner. Teremos sucesso ao acessarmos o nginx e vermos a nossa página index.html. Observação: Neste posto devemos estar dentro da pasta html, volte um nével para executar o comando. Para criarmos e executarmos o contêiner mapeando a pasta, vamos executar o comando abaixo:

$ docker container run --name webservice5 -p 8085:80 -d -v $(pwd)/html:/usr/share/nginx/html nginx

Vamos entender o que ainda não vimos do comando

  • -v: Faz o mapeamento do volume. $(pwd/html) é a pasta de nosso host e após : temos a pasta que iremos direcionar para nosso container, no caso do exemplo a pasta /usr/share/nginx/html

Teremos a apresentação do hash de início do contêiner e para validarmos se tudo ocorreu com sucesso, basta acessarmos em nosso navegador o endereço localhost:8085. O resultado será semelhante ao da imagem abaixo:

ws5.png

E onde posso ver este mapeamento? Para acessar todas as informações do contêiner, utilizaremos o comando abaixo. E em uma parte específica, chamada Mounts, poderemos ver o mapeamento que criamos. A imagem abaixo demonstra as informações do contêiner webservice5.

$ docker container inspect webservice5

mounts.png

Resumo - Comandos Docker listados neste artigo

Segue atividades que enfrentamos neste artigo:

  • Breve apresentação do nginx
  • Criar um contêiner nginx informando a porta http desejada
  • Tentar iniciar um csegundo contêiner com a mesma porta http
  • Executar dois contêineres acessando portas http diferentes
  • Executar um contêiner mapeando uma pasta de nosso host para dentro do contêiner
  • Inspecionamos o contêiner para validarmos o mapeamento
docker container run -d <IMAGE> -d Executa o contêiner com execução em segundo plano, liberando o console que enviou o comando.
docker container logs <CONTAINER NAME> <CONTAINER ID> Lista logs do contêiner desejado.
docker container run -p 8080:80 -p Informa direcionamento e utilização de portas.
docker container inspect <CONTAINER NAME> <CONTAINER ID> Exiber informações do contêiner desejado.

Espero que tenha gostado do conteúdo!

Nos vemos na sequencia da trilha de Docker ou em outro artigo por aqui.

Se você gostou do conteúdo, deixe um comentário ou uma reação para apoiar o projeto! Compartilhe com alguém e ajude a divulgar!

[ ]´s

Degas