Dockerfile no Windows

O Mecanismo do Docker inclui ferramentas que automatizam a criação da imagem de contêiner. Embora você possa criar imagens de contêiner manualmente executando o comando docker commit, a adoção de um processo de criação de imagem automatizado oferece muitos benefícios, incluindo:

  • Armazenar imagens de contêiner como código.
  • Recriação rápida e precisa das imagens de contêiner para fins de manutenção e atualização.
  • Integração contínua entre imagens de contêiner e o ciclo de desenvolvimento.

Os componentes do Docker que orientam essa automação são Dockerfile e o comando docker build.

O Dockerfile é um arquivo de texto que contém as instruções necessárias para criar uma imagem de contêiner. Essas instruções incluem a identificação de uma imagem existente a ser usada como uma base, comandos a serem executados durante o processo de criação da imagem e um comando que será executado quando novas instâncias da imagem de contêiner forem implantadas.

O build do Docker é o comando do Mecanismo do Docker que consome um Dockerfile e dispara o processo de criação de imagem.

Este tópico mostrará como usar Dockerfiles com os contêineres do Windows, entender a sintaxe básica e quais são as instruções mais comuns do Dockerfile.

Este documento abordará o conceito de imagens de contêiner e camadas de imagem de contêiner. Caso deseje saber mais sobre imagens e camadas de imagem, confira Imagens base de contêiner.

Para obter uma visão completa dos Dockerfiles, confira Referência do Dockerfile.

Sintaxe básica

Em sua forma mais básica, um Dockerfile pode ser muito simples. O exemplo a seguir cria uma nova imagem, que inclui o IIS e um site 'hello world'. Este exemplo inclui comentários (indicados com um #), que explicam cada etapa. As seções seguintes deste artigo entrarão em mais detalhes nas regras de sintaxe do Dockerfile e nas instruções do Dockerfile.

Observação

Um Dockerfile precisa ser criado sem nenhuma extensão. Para fazer isso no Windows, crie o arquivo com o editor de sua preferência e, em seguida, salve-o com a notação "Dockerfile" (incluindo as aspas).

# Sample Dockerfile

# Indicates that the windowsservercore image will be used as the base image.
FROM mcr.microsoft.com/windows/servercore:ltsc2019

# Metadata indicating an image maintainer.
LABEL maintainer="jshelton@contoso.com"

# Uses dism.exe to install the IIS role.
RUN dism.exe /online /enable-feature /all /featurename:iis-webserver /NoRestart

# Creates an HTML file and adds content to this file.
RUN echo "Hello World - Dockerfile" > c:\inetpub\wwwroot\index.html

# Sets a command or process that will run each time a container is run from the new image.
CMD [ "cmd" ]

Para obter mais exemplos de Dockerfiles para o Windows, confira o repositório do Dockerfile para Windows.

Instruções

As instruções do Dockerfile fornecem ao Mecanismo do Docker as instruções necessárias para criar uma imagem de contêiner. Essas instruções são executadas em ordem e uma por vez. Os exemplos a seguir são as instruções mais comumente usadas em Dockerfiles. Para obter uma lista completa de instruções do Dockerfile, confira a referência do Dockerfile.

FROM

A instrução FROM define a imagem de contêiner que será usada durante o processo de criação de nova imagem. Por exemplo, ao usar a instrução FROM mcr.microsoft.com/windows/servercore, a imagem resultante é derivada da (e tem uma dependência na) imagem do sistema operacional base Windows Server Core. Se a imagem especificada não estiver presente no sistema em que o processo de build do Docker está sendo executado, o mecanismo do Docker tentará baixar a imagem de um registro da imagem pública ou privada.

O formato da instrução FROM é o seguinte:

FROM <image>

Este é um exemplo do comando FROM:

Para baixar o Windows Server Core versão ltsc2019 do MCR (Registro de Contêiner da Microsoft):

FROM mcr.microsoft.com/windows/servercore:ltsc2019

Para obter informações mais detalhadas, confira a referência de FROM.

EXECUTAR

A instrução RUN especifica os comandos a serem executados e capturados na nova imagem de contêiner. Esses comandos podem incluir itens como a instalação de software, a criação de arquivos e diretórios e a criação da configuração do ambiente.

A instrução RUN é executada da seguinte forma:

# exec form

RUN ["<executable>", "<param 1>", "<param 2>"]

# shell form

RUN <command>

A diferença entre o exec e o shell está em como a instrução RUN é executada. Ao usar o formato exec, o programa especificado é executado explicitamente.

Este é um exemplo do formato exec:

FROM mcr.microsoft.com/windows/servercore:ltsc2019

RUN ["powershell", "New-Item", "c:/test"]

A imagem resultante executa o comando powershell New-Item c:/test:

docker history doc-exe-method

IMAGE               CREATED             CREATED BY                    SIZE                COMMENT
b3452b13e472        2 minutes ago       powershell New-Item c:/test   30.76 MB

Por outro lado, o seguinte exemplo executa a mesma operação no formato de shell:

FROM mcr.microsoft.com/windows/servercore:ltsc2019

RUN powershell New-Item c:\test

A imagem resultante tem uma instrução de execução igual a cmd /S /C powershell New-Item c:\test.

docker history doc-shell-method

IMAGE               CREATED             CREATED BY                              SIZE                COMMENT
062a543374fc        19 seconds ago      cmd /S /C powershell New-Item c:\test   30.76 MB

Considerações sobre o uso de RUN com o Windows

No Windows, ao usar a instrução RUN com o formato de exec., as barras invertidas devem ser seguidas por caracteres de escape.

RUN ["powershell", "New-Item", "c:\\test"]

Quando o programa de destino for um Windows Installer, você precisará extrair a configuração por meio do sinalizador /x:<directory> para iniciar o procedimento de instalação real (silencioso). Você também precisará aguardar a saída do comando antes de executar qualquer outra ação. Caso contrário, o processo será encerrado prematuramente, sem instalar nenhum item. Para obter detalhes, consulte o exemplo a seguir.

Exemplos de como usar RUN com o Windows

O seguinte Dockerfile de exemplo usa o DISM para instalar o IIS na imagem de contêiner:

RUN dism.exe /online /enable-feature /all /featurename:iis-webserver /NoRestart

Este exemplo instala o pacote redistribuível do Visual Studio. O Start-Process e o parâmetro -Wait são usados para executar o instalador. Isso garante que a instalação seja concluída antes de passar para a próxima instrução no Dockerfile.

RUN powershell.exe -Command Start-Process c:\vcredist_x86.exe -ArgumentList '/quiet' -Wait

Para obter informações detalhadas sobre a instrução RUN, confira a referência de RUN.

COPIAR

A instrução COPY copia arquivos e diretórios para o sistema de arquivos do contêiner. Os arquivos e os diretórios precisam estar em um caminho relativo ao Dockerfile.

O formato da instrução COPY é o seguinte:

COPY <source> <destination>

Se a origem ou o destino incluir espaços em branco, coloque o caminho entre colchetes e aspas duplas, conforme mostrado no seguinte exemplo:

COPY ["<source>", "<destination>"]

Considerações sobre o uso de COPY com o Windows

No Windows, o formato de destino deve usar barras "/". Por exemplo, estas são as instruções válidas COPY:

COPY test1.txt /temp/
COPY test1.txt c:/temp/

Enquanto isso, o seguinte formato com barras invertidas não funcionará:

COPY test1.txt c:\temp\

Exemplos de como usar COPY com o Windows

O seguinte exemplo adiciona o conteúdo do diretório de origem a um diretório chamado sqllite na imagem de contêiner:

COPY source /sqlite/

O seguinte exemplo adicionará todos os arquivos que começam com o termo config ao diretório c:\temp da imagem de contêiner:

COPY config* c:/temp/

Para obter informações mais detalhadas sobre a instrução COPY, confira a referência de COPY.

ADD

A instrução ADD é como a instrução COPY, mas com ainda mais funcionalidades. Além de copiar arquivos do host para a imagem de contêiner, a instrução ADD também pode copiar arquivos de um local remoto com uma especificação de URL.

O formato da instrução ADD é o seguinte:

ADD <source> <destination>

Se a origem ou o destino incluir espaços em branco, coloque o caminho entre colchetes e aspas duplas:

ADD ["<source>", "<destination>"]

Considerações sobre a execução de ADD com o Windows

No Windows, o formato de destino deve usar barras "/". Por exemplo, estas são as instruções válidas ADD:

ADD test1.txt /temp/
ADD test1.txt c:/temp/

Enquanto isso, o seguinte formato com barras invertidas não funcionará:

ADD test1.txt c:\temp\

Além disso, no Linux a instrução ADD expandirá pacotes compactados na cópia. Essa funcionalidade não está disponível no Windows.

Exemplos de como usar ADD com o Windows

O seguinte exemplo adiciona o conteúdo do diretório de origem a um diretório chamado sqllite na imagem de contêiner:

ADD source /sqlite/

O exemplo a seguir adicionará todos os arquivos que começam com "config" ao diretório c:\temp da imagem de contêiner.

ADD config* c:/temp/

O exemplo a seguir baixará o Python para Windows no diretório c:\temp da imagem de contêiner.

ADD https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe /temp/python-3.5.1.exe

Para obter informações mais detalhadas sobre a instrução ADD, confira a referência de ADD.

WORKDIR

A instrução WORKDIR define um diretório de trabalho para outras instruções Dockerfile, como RUN, CMD e também o diretório de trabalho para executar instâncias da imagem do contêiner.

O formato da instrução WORKDIR é o seguinte:

WORKDIR <path to working directory>

Considerações sobre o uso de WORKDIR com o Windows

No Windows, se o diretório de trabalho incluir uma barra invertida, ela deverá ser seguida por caracteres de escape.

WORKDIR c:\\windows

Exemplos

WORKDIR c:\\Apache24\\bin

Para obter informações detalhadas sobre a instrução WORKDIR, confira a referência de WORKDIR.

CMD

A instrução CMD, define o comando padrão a ser executado durante a implantação de uma instância da imagem do contêiner. Por exemplo, se o contêiner for hospedar um servidor Web NGINX, o CMD poderá incluir instruções para iniciar o servidor Web, com um comando como nginx.exe. Se várias instruções CMD forem especificadas em um Dockerfile, somente a última será avaliada.

O formato da instrução CMD é o seguinte:

# exec form

CMD ["<executable", "<param>"]

# shell form

CMD <command>

Considerações sobre o uso de CMD com o Windows

No Windows, caminhos de arquivo especificados na instrução CMD devem usar barras "/" ou ter barras invertidas de escape \\. Estas são instruções CMD válidas:

# exec form

CMD ["c:\\Apache24\\bin\\httpd.exe", "-w"]

# shell form

CMD c:\\Apache24\\bin\\httpd.exe -w

No entanto, o seguinte formato sem as barras corretas não funcionará:

CMD c:\Apache24\bin\httpd.exe -w

Para obter informações mais detalhadas sobre a instrução CMD, confira a referência de CMD.

Caractere de escape

Em muitos casos, uma instrução do Dockerfile precisará abranger várias linhas. Para fazer isso, você poderá usar um caractere de escape. O caractere de escape padrão do Dockerfile é uma barra invertida \. No entanto, como a barra invertida também é um separador de caminho de arquivo no Windows, o uso dela para abranger várias linhas pode causar problemas. Para resolver isso, você pode usar uma diretiva do analisador para alterar o caractere de escape padrão. Para obter mais informações sobre diretivas do analisador, confira Diretivas do analisador.

O seguinte exemplo mostra uma só instrução RUN que abrange várias linhas usando o caractere de escape padrão:

FROM mcr.microsoft.com/windows/servercore:ltsc2019

RUN powershell.exe -Command \
    $ErrorActionPreference = 'Stop'; \
    wget https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; \
    Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; \
    Remove-Item c:\python-3.5.1.exe -Force

Para modificar o caractere de escape, coloque uma diretiva do analisador de escape logo na primeira linha do Dockerfile. Isso pode ser visto no exemplo a seguir.

Observação

Apenas dois valores podem ser usados como caracteres de escape: \ e `.

# escape=`

FROM mcr.microsoft.com/windows/servercore:ltsc2019

RUN powershell.exe -Command `
    $ErrorActionPreference = 'Stop'; `
    wget https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; `
    Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; `
    Remove-Item c:\python-3.5.1.exe -Force

Para obter mais informações sobre a diretiva do analisador de escape, confira Diretiva do analisador de escape.

PowerShell no Dockerfile

Cmdlets do PowerShell

Os cmdlets do PowerShell podem ser executados em um Dockerfile com a operação RUN.

FROM mcr.microsoft.com/windows/servercore:ltsc2019

RUN powershell -command Expand-Archive -Path c:\apache.zip -DestinationPath c:\

Chamadas REST

O cmdlet Invoke-WebRequest do PowerShell pode ser útil ao coletar informações ou arquivos de um serviço Web. Por exemplo, se você criar uma imagem que inclui o Python, poderá definir $ProgressPreference como SilentlyContinue para obter downloads mais rápidos, como mostrado no exemplo a seguir.

FROM mcr.microsoft.com/windows/servercore:ltsc2019

RUN powershell.exe -Command \
  $ErrorActionPreference = 'Stop'; \
  $ProgressPreference = 'SilentlyContinue'; \
  Invoke-WebRequest https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe -OutFile c:\python-3.5.1.exe ; \
  Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; \
  Remove-Item c:\python-3.5.1.exe -Force

Observação

Invoke-WebRequest também funciona no Nano Server.

Outra opção para usar o PowerShell para baixar arquivos durante o processo de criação de imagem é usar a biblioteca .Net WebClient. Isso pode aumentar o desempenho do download. O exemplo a seguir baixa o software Python usando a biblioteca WebClient.

FROM mcr.microsoft.com/windows/servercore:ltsc2019

RUN powershell.exe -Command \
  $ErrorActionPreference = 'Stop'; \
  (New-Object System.Net.WebClient).DownloadFile('https://www.python.org/ftp/python/3.5.1/python-3.5.1.exe','c:\python-3.5.1.exe') ; \
  Start-Process c:\python-3.5.1.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; \
  Remove-Item c:\python-3.5.1.exe -Force

Observação

Atualmente, o Nano Server não dá suporte ao WebClient.

Scripts do PowerShell

Em alguns casos, pode ser útil copiar um script para os contêineres que estão sendo usados durante o processo de criação da imagem e, em seguida, executar o script no contêiner.

Observação

Isso limitará qualquer cache de camada de imagem e diminuirá a legibilidade do Dockerfile.

Este exemplo copia um script do computador de build para o contêiner usando a instrução ADD. Esse script é executado usando a instrução RUN.

FROM mcr.microsoft.com/windows/servercore:ltsc2019
ADD script.ps1 /windows/temp/script.ps1
RUN powershell.exe -executionpolicy bypass c:\windows\temp\script.ps1

Build do Docker

Depois de criar e salvar um Dockerfile em disco, você poderá executar docker build para criar a imagem. O comando docker build leva vários parâmetros opcionais e um caminho para o Dockerfile. Para obter a documentação completa sobre o Build do Docker, incluindo uma lista de todas as opções de build, confira a referência de build.

O formato do comando docker build é o seguinte:

docker build [OPTIONS] PATH

Por exemplo, o comando a seguir criará uma imagem chamada "iis".

docker build -t iis .

Quando o processo de build for iniciado, a saída indicará o status e retornará os erros gerados.

C:\> docker build -t iis .

Sending build context to Docker daemon 2.048 kB
Step 1 : FROM mcr.microsoft.com/windows/servercore:ltsc2019
 ---> 6801d964fda5

Step 2 : RUN dism /online /enable-feature /all /featurename:iis-webserver /NoRestart
 ---> Running in ae8759fb47db

Deployment Image Servicing and Management tool
Version: 10.0.10586.0

Image Version: 10.0.10586.0

Enabling feature(s)
The operation completed successfully.

 ---> 4cd675d35444
Removing intermediate container ae8759fb47db

Step 3 : RUN echo "Hello World - Dockerfile" > c:\inetpub\wwwroot\index.html
 ---> Running in 9a26b8bcaa3a
 ---> e2aafdfbe392
Removing intermediate container 9a26b8bcaa3a

Successfully built e2aafdfbe392

O resultado é uma nova imagem de contêiner, que, neste exemplo, é chamada "iis".

docker images

REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
iis                 latest              e2aafdfbe392        About a minute ago   207.8 MB
windowsservercore   latest              6801d964fda5        4 months ago         0 B

Referências e leituras adicionais