Docker – Como criar uma imagem Docker a partir de um Container utilizando o Docker commit

Você pode criar uma imagem a partir de um container, por exemplo você criou um container qualquer, configurou as aplicações, serviços, instalou os pacotes necessários, enfim deixou o container pronto para uso.

Para não ter que repetir este processo toda vez, é possível criar uma imagem a partir deste container com o comando docker commit e distribuir a imagem para outros hosts Docker, Publicar no Docker Hub ou Docker Registry, ou simplesmente empacotar com o tar e distribuir da melhor forma que você achar. Vamos ver como isto funciona.

Criando uma container

#docker run -ti --name webserver-nginx -h webserver-nginx ubuntu /bin/bash

Criei um container com o nome webserver-nginx e hostname webserver-nginx.
Utilizei a imagem pública Ubuntu, que foi baixada do Docker Hub.
Instalei o Nginx e configurei, atualizei a imagem, instalei o Php e etc.

Criando uma imagem

#docker commit 3b64e4b39127 imagemnginx:versao1

3b64e4b39127 – É o ID do nosso container, é a partir dele que vamos fazer o commit e criar uma nova imagem. Você pode consultar o id do container pelo comando “docker ps”.
3b64e4b39127 → webserver-nginx

imagemnginx:versao1 – Criamos uma imagem com a tag versao1. Quando você atualizar uma imagem é recomendado você atualizar a tag, ela é o seu controle de versão.

Criação e consulta da imagem

[root@docker-engine1 ~]# docker commit 3b64e4b39127 imagemnginx:versao1
sha256:fc511188b2fadc7a6aa3c97b10d4f1e32eeab4721571690d5f90d949b8bedefa

[root@docker-engine1 ~]# docker images
REPOSITORY                                        TAG                 IMAGE ID            CREATED             SIZE
imagemnginx                                       versao1          fc511188b2fa     21 seconds ago   291.4 MB

Utilizando a nova imagem
Vamos criar um container a partir desta nova imagem.
docker run -ti -p 80:80 –name novo-nginx -h novo-nginx imagemnginx:versao1

[root@docker-engine1 ~]# docker run -ti -p 80:80 --name novo-nginx -h novo-nginx imagemnginx:versao1 /bin/bash
root@novo-nginx:/# dpkg -l| grep nginx
ii  nginx                           1.4.6-1ubuntu3                   all          small, powerful, scalable web/proxy server
ii  nginx-common                    1.4.6-1ubuntu3                   all          small, powerful, scalable web/proxy server - common files
ii  nginx-core                      1.4.6-1ubuntu3                   amd64        nginx web/proxy server (core version)

root@novo-nginx:/# [root@docker-engine1 ~]# 
[root@docker-engine1 ~]# docker ps
CONTAINER ID        IMAGE                 COMMAND             CREATED             STATUS              PORTS                NAMES
e169316ec53b        imagemnginx:versao1   "/bin/bash"         40 seconds ago      Up 38 seconds       0.0.0.0:80->80/tcp   novo-nginx

Distribuindo as imagens
Tudo pronto, mas e agora como distribuir esta imagem?.
Você pode subir esta imagem para o Docker Hub, ou você pode copiar para um repositório local criado com o Docker Registry ou então empacotar com o tar.

Distribuindo as imagens através do Docker Registry
Também aplica-se para o Docker hub, a ideia é a mesma.

Eu já publiquei um tutorial ensinando a criar um repositório local com o Docker Registry, você pode conferir neste link Como criar um Docker Registry. O conceito é o mesmo para o Docker hub.

Registre a imagem no Docker Registre

#docker tag imagemnginx:versao1 repo-dockerimages.devopslab.com.br:5000/imagemnginx:versao1

Copie a imagem para o Docker Registry

#docker push repo-dockerimages.devopslab.com.br:5000/imagemnginx:versao1
[root@docker-engine1 ~]# docker tag imagemnginx:versao1 repo-dockerimages.devopslab.com.br:5000/imagemnginx:versao1
[root@docker-engine1 ~]# 

[root@docker-engine1 ~]# docker push repo-dockerimages.devopslab.com.br:5000/imagemnginx:versao1
The push refers to a repository [repo-dockerimages.devopslab.com.br:5000/imagemnginx]
761e340d23af: Pushed 
5f70bf18a086: Pushed 
1b82ce694c3b: Pushed 
db6b2d84f3c6: Pushed 
05b940eef08d: Pushed 
versao1: digest: sha256:1476afd82aa17a0aa31747bf57df182c4e2486e5c7bb7ee3384f726adc472af5 size: 1341

Utilizando a imagem a partir de qualquer host da rede

Logue em qualquer Docker Host da sua rede e tente criar um container.

[root@docker-engine2 /]# docker run -ti --name nginx-testeimage -h nginx-testeimage repo-dockerimages.devopslab.com.br:5000/imagemnginx:versao1 bash

root@nginx-testeimage:/# dpkg -l | grep nginx
ii  nginx                           1.4.6-1ubuntu3                   all          small, powerful, scalable web/proxy server
ii  nginx-common                    1.4.6-1ubuntu3                   all          small, powerful, scalable web/proxy server - common files
ii  nginx-core                      1.4.6-1ubuntu3                   amd64        nginx web/proxy server (core version)

root@nginx-testeimage:/# [root@docker-engine2 /]# 

[root@docker-engine2 /]# docker ps
CONTAINER ID        IMAGE                                                         COMMAND             CREATED             STATUS              PORTS               NAMES
f31d5a478bf9        repo-dockerimages.devopslab.com.br:5000/imagemnginx:versao1   "bash"              17 seconds ago      Up 15 seconds                           nginx-testeimage

Distribuindo as imagens na mão via pacote tar
Vou mostar como exportar e importar uma imagem Docker via pacote tar. Isto é uma opção em relação ao Docker Registry e Docker Hub.

Exportando a imagem
Primeiramente salve a imagem para um arquivo .tar.

#docker save repo-dockerimages.devopslab.com.br:5000/imagemnginx:versao1 > /tmp/minha-imagem.tar

[root@docker-engine1 ~]# docker save repo-dockerimages.devopslab.com.br:5000/imagemnginx:versao1 > /tmp/minha-imagem.tar
[root@docker-engine1 ~]# ls -lh /tmp/minha-imagem.tar
-rw-r--r-- 1 root root 291M Mar 30 00:49 /tmp/minha-imagem.tar

Importando a imagem
Importando a imagem
Agora basta copiar a imagem empacotada minha-imagem.tar para qualquer host e importar.

#docker load < minha-imagem.tar

root@docker-engine4 ~]# docker load < minha-imagem.tar 

[root@docker-engine4 ~]# docker images
REPOSITORY                                            TAG                 IMAGE ID            CREATED             SIZE
repo-dockerimages.devopslab.com.br:5000/imagemnginx   versao1             fc511188b2fa        About an hour ago   291.4 MB

[root@docker-engine4 ~]# docker run -ti --name container-teste-import -h container-teste-import repo-dockerimages.devopslab.com.br:5000/imagemnginx:versao1 bash

root@container-teste-import:/# dpkg -l | grep nginx
ii  nginx                           1.4.6-1ubuntu3                   all          small, powerful, scalable web/proxy server
ii  nginx-common                    1.4.6-1ubuntu3                   all          small, powerful, scalable web/proxy server - common files
ii  nginx-core                      1.4.6-1ubuntu3                   amd64        nginx web/proxy server (core version)
root@container-teste-import:/# 

[root@docker-engine4 ~]# docker ps
CONTAINER ID        IMAGE                                                         COMMAND             CREATED             STATUS              PORTS               NAMES
deb7cd78e920        repo-dockerimages.devopslab.com.br:5000/imagemnginx:versao1   "bash"              51 seconds ago      Up 50 seconds                           container-teste-import

Até a próxima.

Leonardo Macedo Cerqueira

Docker – Como instalar o Docker – criaçao de imagens e container

Tutorial de como instalar o Docker, criar imagens fazendo pull do Docker hub e criação de container.

Este é um tutorial prático, o objetivo é mão na massa. Detalhes técnicos e definições relevantes vou mencionar no próprio tutorial porém se você quer mais detalhes de cada coisa sugiro dar uma olhada na documentação oficial.

Infraestrutura e Pré-requisitos

Host Docker: CentOS 7 X86_64 instalação mínima.

Por questões de facilidade desative o SElinux e Firewall.

#systemctl stop firewalld; systemctl disable firewalld
#setenforce 0; sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config

1. Criação do repositório Docker

Crie um repositório Docker em todos os hosts que vão rodar o Docker.

#vi /etc/yum.repos.d/docker.repo

[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg

2. Instalação do Docker Engine

Instale o Docker Engine (ou simplesmente Docker) em todos os hosts que vão rodar containers.
Docker Engine é a principal ferramenta no ecossistema Docker, ela é que de fato vai criar e gerenciar os containers.

Instalação do Docker Egine, start e habilitação no boot.

#yum -y install docker-engine
#systemctl start docker
#systemctl enable docker

3. Teste de funcionamento do Docker

Com o Docker Engine instalado faça um teste funcional subindo uma imagem de teste.

O Comando docker run vai checar se existe uma imagem hello-word.
Se não existir ele vai baixar a imagem do repositório Docker Hub.
E carregá-la dentro de um container e rodar.
#docker run hello-world

#docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world

03f4658f8b78: Pull complete 
a3ed95caeb02: Pull complete 
Digest: sha256:8be990ef2aeb16dbcb9271ddfe2610fa6658d13f6dfb8bc72074cc1ca36966a7
Status: Downloaded newer image for hello-world:latest

Hello from Docker.
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
$docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker Hub account:
https://hub.docker.com

For more examples and ideas, visit:
https://docs.docker.com/userguide/

Se você teve uma saída parecida seu Docker está funcionando.

4. Instalação de Imagens e criação de container

Com o Docker Engine instalado e rodando vamos procurar imagens no repositório Docker hub e começar a trabalhar.

Existem centenas de imagens, e o comando para buscar imagens é o “docker search” que vai procurar imagens no Docker Hub.

Você também pode procurar imagens diretamente na url https://hub.docker.com/

Procurando a imagem Ubuntu
#docker search ubuntu

Vamos baixar a última versão do ubuntu.
#docker pull ubuntu

Se você quiser baixar uma versão específica faça:
#docker pull ubuntu:14:04

# docker pull ubuntu
Using default tag: latest
latest: Pulling from library/ubuntu
203137e8afd5: Pull complete 
2ff1bbbe9310: Pull complete 
933ae2486129: Pull complete 
a3ed95caeb02: Pull complete 
Digest: sha256:1bea66e185d3464fec1abda32ffaf2a11de69833cfcf81bd2b9a5be147776814
Status: Downloaded newer image for ubuntu:latest

Verificando a lista de imagens instaladas.
#docker images

#docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
ubuntu              latest              97434d46f197        5 days ago          187.9 MB
hello-world         latest              690ed74de00f        5 months ago        960 B

Criação de um Container
Criação de um container em modo interativo (com um terminal bash).

#docker run -i -t ubuntu bash

Você acabou de iniciar um container e já pode instalar aplicações e configurar o Sistema Operacional como bem entender.

Perceba que o container tem um IP, no meu caso 172.17.0.2, o próprio Docker é encarregado de criar uma rede dedicada aos containers.

É por este ip que você vai acessar as aplicações instaladas no container.

root@6d83aa2a68b4:/# ip addr | grep eth0
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    inet 172.17.0.2/16 scope global eth0

O ID do meu container é 6d83aa2a68b4 consultado pelo comando “docker ps”.

Comandos úteis
docker ps – Lista os containers rodando.
docker ps -a – Lista todos os últimos containers utilizados.
docker stats – Estátisticas de uso dos containers.

ctrl-p + ctrl-q (control q + Control p) – Você vai fazer um “detach” do tty sem sair do shell, seria equivalente a “deslogar” do container porém mantendo tudo rodando.

docker attach id-container – Você vai abrir um sessão tty em um container rodando. (exemplo docker attach 6d83aa2a68b4).

5. Instalação de aplicações no container

Instale por exemplo o Nginx ou até mesmo um Tomcat no container e você poderá acessar a aplicação a partir do host rodando o Docker Engine.

Lembrando que meu host Docker Engine é um CentOS 7.

Acessando meu container Ubuntu.

root@docker-engine1:/#docker attach 6d83aa2a68b4
root@6d83aa2a68b4:/# aptitude install nginx
root@6d83aa2a68b4:/#/etc/init.d/nginx start

Teste a partir do host Docker Engine.

[root@docker-engine1 /]# curl 172.17.0.2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

Bom aprendemos como instalar o Docker.
Buscar e instalar imagens no Docker Hub.
Instalação e acesso a aplicações dentro de um container.

6. Expondo uma porta do Host Docker – Bind de um serviço em uma porta TCP do Host Docker

Sua aplicação até o momento pode ser acessada apenas a partir host Docker.

Porém você quer que esta aplicação fique acessível para todos os outros servidores e clientes da rede e não apenas ao Host Docker.

Meu host docker tem o IP 10.0.2.201.
Meu container tem o IP 172.17.0.2.

O que nós vamos fazer é expor uma porta no Docker Host e mapeá-la para o cotainer.

Suba um container da seguinte forma:
#docker run -i -t -p 80:80 ubuntu bash

O que acontece aqui é o seguinte:
-> 1 – Iniciamos um container conforme já fizemos nos passos anteriores.
-> 2 – Fizemos um redirecionamento de portas, traduzindo acontece isto.
10.0.2.201:80 —-> 172.17.0.2:80
NAT de 10.0.2.201:80 para 172.17.0.2:80

Ou seja quando você acessar a porta 80 tcp do ip do Docker “10.0.2.201:80” você será redirecionado para o container na porta 80 tcp “172.17.0.2:80”.

Olha que lindo, agora sua aplicação dentro do container está disponível para sua rede.

Por curiosidade você pode verificar as regras de nat criado pelo Docker, então no host do Docker faça:
#iptables -L
#iptables -t nat -L

7. Configurando um hostname e um nome para o container

Acessar um container por um ID não é algo muito amigável por exemplo:
#docker attach 6d83aa2a68b4

O ideal é você criar um nome mais acessível, então vamos fazer o seguinte, setar o hostname no container e criar um nome para o container.

#docker run --name webserver-nginx1 -h webserver-nginx1.devopslab.com.br -i -t -p 80:80 ubuntu bash

–name webserver-nginx1 – Aqui nós definimos um nome para o container, então quando quisermos conectar nele vamos fazer:
#docker attach webserver-nginx1

Para verificar o nome do container faça simplesmente “docker ps”.
-h webserver-nginx1.devopslab.com.br – Aqui nós definimos um hostname já no padrão fqdn para o container.

Parte prática.

[root@docker-engine1 ~]# docker run --name webserver-nginx1 -h webserver-nginx1.devopslab.com.br -i -t -p 80:80 ubuntu bash
root@webserver-nginx1:/# hostname
webserver-nginx1.devopslab.com.br
root@webserver-nginx1:/# [root@docker-engine1 ~]# 
[root@docker-engine1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
5e657b71cb76        ubuntu              "bash"              2 minutes ago       Up 2 minutes        0.0.0.0:80->80/tcp   webserver-nginx1
[root@docker-engine1 ~]# docker attach webserver-nginx1
root@webserver-nginx1:/# hostname
webserver-nginx1.devopslab.com.br

Veja que eu fiz o processo de criação de um container, verificação do hostname e attach pelo nome ao invés de ID.

8. Permissionamento – executando o Docker com um usuário comum

Toda administração dos containers docker que fizemos até agora foi com o usuário root, no entanto é recomendável administrar os containers com usuários comuns.

Assim que você instala o docker engine, também é criado um grupo “docker”, sendo assim basta você adicionar seus usuários ao grupo docker.

Parte prática.

[root@docker-engine1 ~]# grep docker /etc/group
docker:x:993:

[root@docker-engine1 ~]# gpasswd -a leonardo docker
Adding user leonardo to group docker

root@docker-engine1 ~]# su - leonardo
[leonardo@docker-engine1 ~]$ 

[leonardo@docker-engine1 ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

[leonardo@docker-engine1 ~]$ docker start webserver-nginx1
webserver-nginx1

[leonardo@docker-engine1 ~]$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                NAMES
5e657b71cb76        ubuntu              "bash"              4 hours ago         Up 2 seconds        0.0.0.0:80->80/tcp   webserver-nginx1

[leonardo@docker-engine1 ~]$ docker attach webserver-nginx1
root@webserver-nginx1:/# 

Referência.
https://docs.docker.com/userguide/

Leonardo Macedo Cerqueira