Seguindo com nossa série de artigos sobre usar Docker no Windows 10, neste artigo vamos detalhar um pouco mais os recursos para criação de uma imagem Docker customizada.
Seguem os outros artigos da série:
– Introdução ao Docker no Windows 10, onde abordamos a instalação e setup.
– Uso de uma imagem oficial Apache Httpd para publicar páginas Web.
– Uso de composição de containers para definição de uma infra-estrutura de containers.
Fontes:
– http://developers.redhat.com/blog/2014/05/15/practical-introduction-to-docker-containers/
– https://docs.docker.com/engine/tutorials/dockerimages/
O Dockerfile: Visão geral
O Dockerfile é um arquivo que define uma imagem Docker. Todas as imagens Docker presentes do Docker Explore tem um Dockerfile.
Por exemplo, segue Dockerfile da última versão (latest) do Nginx:
FROM debian:jessie MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com" ENV NGINX_VERSION 1.11.5-1~jessie RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 \ && echo "deb http://nginx.org/packages/mainline/debian/ jessie nginx" >> /etc/apt/sources.list \ && apt-get update \ && apt-get install --no-install-recommends --no-install-suggests -y \ ca-certificates \ nginx=${NGINX_VERSION} \ nginx-module-xslt \ nginx-module-geoip \ nginx-module-image-filter \ nginx-module-perl \ nginx-module-njs \ gettext-base \ && rm -rf /var/lib/apt/lists/* # forward request and error logs to docker log collector RUN ln -sf /dev/stdout /var/log/nginx/access.log \ && ln -sf /dev/stderr /var/log/nginx/error.log EXPOSE 80 443 CMD ["nginx", "-g", "daemon off;"]
Com base no exemplo acima, vamos ver algumas opções do Dockerfile.
– Linha 1 Definição da imagem de origem. A imagem não será criada do zero, mas sim a partir de uma outra imagem, a “debian:jessie”.
– Linha 3 Indicação dos mantenedores dessa imagem.
– Linha 5 Configuração de variável de ambiente, informando a versão do Nginx.
– Linha 7 Execução de comandos no debian para instalar o Nginx na imagem (usando apt-get).
– Linha 22 Execução de comandos no debian para encaminhar logs para os arquivos dentro do caminho /var/log/nginx/
.
– Linha 25 Exposição das portas 80 e 443 da imagem.
– Linha 27 Definição do comando que será executado quando um container gerado a partir dessa imagem for iniciado.
Para informações sobre as opções para configuração do Dockerfile, acesse o link https://docs.docker.com/engine/reference/builder/.
E conforme já visto nos outros artigos dessa série, essa imagem definida pela Dockerfile pode ser referenciada tanto no comando docker
como também no arquivo docker-compose.yml
.
Criando um Dockerfile
Para criar o Dockerfile, você pode usar um editor simples. Mas recursos como auto-complete e highlight são sempre bem vindos. Aqui vamos usar o Visual Studio Code com a extensão Dockerfile and Docker Compose File (yml) Support:
Como exemplo, criaremos uma imagem Maven com JDK 1.8 para compilar projetos Java com Maven. Ao procurar no Docker Explore, veja que há várias imagens maven. Vamos selecionar a imagem 3.3.9-jdk-8
. E para essa nova imagem, incluiremos o git
via apt-get
:
FROM maven:3.3.9-jdk-8 # Install software RUN apt-get install -y git RUN mkdir /usr/src/app WORKDIR /usr/src/app CMD tail -f /dev/null
Notas:
- Criei uma pasta
/usr/src/app
e definindo ela como pasta de trabalho (WORKDIR) que equivale ao comandocd
.- Estou usando aqui o
CMD
na definição da imagem (comando executado quando o container inicia) para manter o container em execução. Isso porque, por padrão, quando um container é iniciado, ele executa o comando configurado para ele e finaliza quando o comando terminar. Pode-se também usar outro comando ou um script que mantenha o container em execução. No caso do Nginx acima, é usado o próprio servidornginx
.
Para criar a imagem, vamos para o Prompt (ou Powershell), acessar o diretório onde criamos o Dockerfile e executar a seguinte linha de comando:
C:\docker>docker build . Sending build context to Docker daemon 50.26 MB Step 1 : FROM maven:3.3.9-jdk-8 ---> 7d77e2359e4b Step 2 : RUN apt-get install -y git ---> Using cache ---> 98b7ab407302 Step 3 : RUN mkdir /usr/src/app ---> Using cache ---> 024747703e49 Step 4 : WORKDIR /usr/src/app ---> Using cache ---> 9ce13b80a47b Step 5 : CMD tail -f /dev/null ---> Using cache ---> 4021ac9ebb2a Successfully built 4021ac9ebb2a SECURITY WARNING: You are building a Docker image from Windows against a non-Windows Docker host. All files and directories added to build context will have '-rwxr-xr-x' permissions. It is recommended to double check and reset permissions for sensitive files and directories. C:\docker>
Notas:
- No meu caso a imagem foi criada a partir de outras imagens que eu tinha criado anteriormente (using cache). No seu caso pode ser necessário baixar imagens remotamente.
- Para visualizar nossa imagem, executamos o comando
docker images
. O ID da imagem é citado no final. No meu caso é o4021ac9ebb2a
.
Agora vamos criar e iniciar um container a partir dessa imagem usando o comando docker create --name MyContainer [IMAGE_ID]
. Meu [IMAGE_ID]
é 4021ac9ebb2a
.
C:\docker>docker create --name MyContainer 4021ac9ebb2a fbe07a630e91414c8b2042b733a5b44b47db98811535aa1e82448f13d111c948 C:\docker>docker start MyContainer MyContainer C:\docker>
Depois disso, podemos usar o container para executar comandos. Para demonstração, vamos clonar um repositório Git com projeto Maven e compilar o projeto com Maven (por exemplo, o repositório https://github.com/imglib/imglib2):
C:\docker>docker exec MyContainer git clone https://github.com/imglib/imglib2.git .
C:\docker>docker exec MyContainer mvn
Os comandos acima serão executados dentro do
WORKDIR
que definidos no Dockerfile.
Terminado o processo, podemos agora executar, por exemplo, o comando Bash de forma interativa para acessar o conteúdo compilado pelo nosso container. E para copiar um determinado arquivo de dentro do container, usamos o comando docker cp
direto do nosso host:
C:\docker>docker exec -it MyContainer bash root@fbe07a630e91:/usr/sdoc pom.xml src target root@fbe07a630e91:/usr/src/app# cd target root@fbe07a630e91:/usr/src/app/target# ls classes imglib2-3.2.2-SNAPSHOT-tests.jar maven-statuser test-classes generated-test-sources imglib2-3.2.2-SNAPSHOT.jar surefire-reports root@fbe07a630e91:/usr/src/app/target# exit exit C:\docker>docker cp MyContainer:/usr/src/app/target/imglib2-3.2.2-SNAPSHOT.jar . C:\docker>dir Volume in drive C is OSDisk Volume Serial Number is 34BB-56DE Directory of C:\docker 28/10/2016 11:07 >DIR> . 28/10/2016 11:07 >DIR< .. 28/10/2016 10:29 148 Dockerfile 27/10/2016 20:12 604.821 imglib2-3.2.2-SNAPSHOT.jar 2 File(s) 604.969 bytes 2 Dir(s) 7.781.826.560 bytes free C:\docker>
Pronto! Criamos um container a partir de uma imagem Maven, baixamos nele um repositório Git, compilamos e depois pegamos o arquivo JAR gerado.
O Docker Hub: Subindo nossa imagem
Criamos aqui uma imagem personalizada e ainda executamos um container sobre a imagem. Podemos agora subir essas modificações direto no Docker Hub, usando nossa conta. Se você ainda não tem, crie uma conta no Docker Hub.
Depois disso, volte para a linha de comando para fazer login, usando a conta recém criada, através do comando docker login
:
C:\docke>docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username (joaocunhaeld): Password: Login Succeeded
Agora temos que definir qual imagem queremos subir para nossa conta do Docker Hub. Podemos usar a imagem original ou ainda gerar uma imagem a partir das mudanças feitas no container que criamos, o MyContainer
.
Para subir a imagem original precisamos definir uma tag (exemplo, my-maven-img:original) para a imagem e fazer push:
C:\docker>docker tag 4021ac9ebb2a my-maven-img C:\docker>docker tag 4021ac9ebb2a joaocunhaeld/my-maven-img:original C:\docker>docker push joaocunhaeld/my-maven-img:original The push refers to a repository [docker.io/joaocunhaeld/my-maven-img] 5f85e80cd5ef: Pushed f68ec8cbf3e2: Pushed 7e074b280d4a: Pushed 6339c6454299: Mounted from library/maven a49358240350: Mounted from library/maven 3ab252edeedb: Mounted from library/maven cafbf8599061: Mounted from library/maven 271ee5f59d19: Mounted from library/maven 294aa583a65a: Mounted from library/maven c5bb6583fe2c: Mounted from library/maven b376ebfc5566: Mounted from library/openjdk 33c3a104206a: Mounted from library/openjdk 149636c85012: Mounted from library/openjdk f96222d75c55: Mounted from library/php latest: digest: sha256:0bda230011b65ecf02a142f588a4446014bf9756b0003e00667ddeed421cb8a4 size: 3251 C:\docker>
A tag que usei foi
my-maven-img:original
para a contajoaocunhaeld
.
Já para o container precisamos fazer um passo a mais que é o commit das mudanças feitas nele. Isso porque o container tem uma imagem gerada a partir da imagem original (como um branch) com modificações que realizamos no container. E essas modificações precisam ser confirmadas (commit) caso queiramos subir elas no repositório (caso contrário subiremos a imagem original). E para ver informações da nossa imagem, usar o comando docker images -a [USER]/[IMAGE-NAME]
:
C:\docker>docker commit MyContainer sha256:f03d50fafe814234e898b98c2149e12454ee1c9ca44fbdc51ac9282e975fa828 C:\docker>docker images -a joaocunhaeld/my-maven-img REPOSITORY TAG IMAGE ID CREATED SIZE joaocunhaeld/my-maven-img latest f03d50fafe81 15 hours ago 704.2 MB joaocunhaeld/my-maven-img original 4021ac9ebb2a 16 hours ago 651.1 MB C:\docker>
Notem que temos a imagem my-maven-img:original
, criada através do container 4021ac9ebb2a
e a imagem my-maven-img:latest
gerada a partir do commit que fizemos do nosso container. Vamos agora confirmar as mudanças fazendo um novo push:
C:\docker>docker push joaocunhaeld/my-maven-img
E agora tanto a imagem original como latest (com as alterações que fizemos no container) são públicas e estão disponíveis no Docker Hub. E qualquer outra pessoa pode obter nossas imagens através do comado docker pull joaocunhaeld/my-maven-img
. Se não especificar a versão, será obtido o latest
.
Próximos Passos
Apresentei nesse artigo como criar uma imagem usando o Dockerfile e executar comandos em um container. Depois disso ainda subi tanto a imagem original como as mudanças feitas no container na minha conta do Docker Hub. Em um próximo artigo irei descrever como usar o Docker no Azure e criar um Docker Registry personalizado para manter suas imagens fora do domínio público.
E fiquem a vontade para sugerir exemplos para demonstrarmos aqui. Abraços e até a próxima.
Veja, muito bom seus artigos, vc poderia agora falar sobre acessar docker pela rede local, configurar nat ou bridge, instalar tipo seafile, pois realmente não consegui, até instalei um servidor seafile no windows 10 pro, mas não consigo enxergar ele na rede pelo outro micro win7. Como faço para transformar de mode bridge pra overlay (eu acho) e dessa forma poder acessar de outro micro. Obrigado
CurtirCurtir
Voce poderia fazer a gentileza de mostrar como intalar um servidor seafile, acho até que eu consegui, mas o problema é que não consigo enxerga-lo na rede, tipo no meu note do win7. Acredito que configurar bridge ou overlay seja complexo, esse lance de ip estático também complica, ajuda ai por favor… Obrigado.
CurtirCurtir