Dockerfile en Windows

El motor de Docker incluye herramientas que automatizan la creación de imágenes de contenedor. Aunque puedes crear imágenes de contenedor manualmente con el comando docker commit, la adopción de un proceso automatizado de creación de imágenes tiene numerosas ventajas, entre otras las siguientes:

  • Almacenamiento de las imágenes del contenedor como código.
  • Posibilidad de volver a crear de manera rápida y precisa las imágenes del contenedor con fines de mantenimiento y actualización.
  • Integración continua entre las imágenes del contenedor y el ciclo de desarrollo.

Los componentes de Docker que controlan esta automatización son el archivo Dockerfile y el comando docker build.

Dockerfile es un archivo de texto que contiene las instrucciones necesarias para crear una nueva imagen del contenedor. Estas instrucciones incluyen la identificación de una imagen existente que se usará como base, los comandos que se ejecutarán durante el proceso de creación de la imagen y un comando que se ejecutará cuando se implementen instancias nuevas de la imagen del contenedor.

Docker build es el comando del motor de Docker que consume un archivo Dockerfile y desencadena el proceso de creación de la imagen.

En este tema se muestra cómo usar los archivos Dockerfile con contenedores de Windows, entender su sintaxis básica y cuáles son las instrucciones de Dockerfile más comunes.

En este documento se describirá el concepto de imágenes de contenedor y las capas de imagen de contenedor. Si quieres obtener más información sobre las imágenes y el nivel de imagen, consulta las imágenes base de contenedor.

Para obtener información detallada sobre los archivos Dockerfile, consulta la referencia sobre Dockerfile.

Sintaxis básica

En su forma más básica, un archivo Dockerfile puede ser muy simple. En el ejemplo siguiente se crea una imagen, que incluye IIS, y un sitio de "hello world". Este ejemplo incluye comentarios (indicados con el símbolo #) que explican cada paso. En las secciones posteriores del artículo se ofrecerá más información sobre las reglas de sintaxis de Dockerfile y las instrucciones Dockerfile.

Nota

Dockerfile debe crearse sin extensión. Para hacer eso en Windows, crea el archivo con el editor que quieras y, a continuación, guárdalo con la notación "Dockerfile" (incluidas las comillas).

# 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 obtener ejemplos adicionales de Dockerfiles para Windows, consulta el repositorio de Dockerfile para Windows.

Instructions

En las instrucciones de Dockerfile se proporcionan al motor de Docker las instrucciones necesarias para crear una imagen del contenedor. Estas instrucciones se ejecutan en orden y una a una. En los ejemplos siguientes encontrarás las instrucciones más usadas en Dockerfiles. Para obtener una lista completa de las instrucciones de Dockerfile, consulta la referencia de Dockerfile.

FROM

La instrucción FROM establece la imagen del contenedor que se usará durante el proceso de creación de la imagen. Por ejemplo, cuando se usa la instrucción FROM mcr.microsoft.com/windows/servercore, la imagen resultante deriva de la imagen base del sistema operativo de Windows Server Core y tiene una dependencia en esta. Si la imagen especificada no está presente en el sistema donde se ejecuta el proceso de compilación de Docker, el motor de Docker intentará descargar la imagen de un Registro de imágenes público o privado.

El formato de la instrucción FROM es similar al siguiente:

FROM <image>

A continuación, presentamos un ejemplo del comando FROM:

Para descargar la versión ltsc2019 de Windows Server Core del Microsoft Container Registry (MCR):

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

Para obtener información detallada, consulta la referencia de FROM.

EJECUTAR

La instrucción RUN especifica los comandos que se ejecutarán y se capturarán en la nueva imagen del contenedor. Estos comandos pueden incluir elementos como la instalación de software, la creación de archivos y directorios y la creación de la configuración del entorno.

La instrucción RUN es como sigue:

# exec form

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

# shell form

RUN <command>

La diferencia entre exec form y shell form es la manera en que se ejecuta la instrucción RUN. Cuando se usa el método exec form, el programa especificado se ejecuta explícitamente.

A continuación, presentamos un ejemplo de exec form:

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

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

La imagen resultante ejecuta el 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 otro lado, en el ejemplo siguiente se ejecuta la misma operación con shell form:

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

RUN powershell New-Item c:\test

La imagen resultante tiene una instrucción Run de 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

Consideraciones sobre el uso RUN con Windows

En Windows, cuando se usa la instrucción RUN con el formato exec, las barras diagonales inversas deben llevar un símbolo de escape.

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

Cuando el programa de destino es un instalador de Windows, tendrás que extraer el programa de instalación a través de la marca /x:<directory> antes de poder iniciar el procedimiento de instalación (silencioso) real. También debes esperar a que el comando salga antes de hacer nada más. De lo contrario, el proceso finalizará prematuramente, sin instalar nada. Para más información, vea el siguiente ejemplo.

Ejemplos del uso de RUN con Windows

En el ejemplo siguiente, Dockerfile usa DISM para instalar IIS en la imagen del contenedor:

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

En este ejemplo se instala el paquete redistribuible de Visual Studio. Start-Process y el parámetro -Wait se usan para ejecutar el programa de instalación. Esto garantiza que se completa la instalación antes de pasar a la siguiente instrucción del Dockerfile.

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

Para información detallada sobre la instrucción RUN, consulta la referencia sobre RUN.

COPY

La instrucción COPY copia archivos y directorios en el sistema de archivos del contenedor. Los archivos y los directorios deben encontrarse en una ruta de acceso relativa al archivo Dockerfile.

El formato de la instrucción COPY es similar al siguiente:

COPY <source> <destination>

Si el origen o el destino incluyen espacios en blanco, escribe la ruta de acceso entre corchetes y comillas dobles, como se muestra en el siguiente ejemplo:

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

Consideraciones sobre el uso COPY con Windows

En Windows, el formato de destino debe usar barras diagonales. Por ejemplo, las siguientes son instrucciones COPY válidas:

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

Mientras tanto, el formato siguiente con barras diagonales inversas no funcionará:

COPY test1.txt c:\temp\

Ejemplos del uso de COPY con Windows

En el ejemplo siguiente se agrega el contenido del directorio de origen a un directorio denominado sqllite en la imagen del contenedor:

COPY source /sqlite/

En el ejemplo siguiente se agregan todos los archivos que comienzan por config al directorio c:\temp de la imagen del contenedor:

COPY config* c:/temp/

Para obtener información detallada sobre la instrucción COPY, consulta la referencia sobre COPY.

ADD

La instrucción ADD es similar a la instrucción COPY, pero con más funcionalidades. Además de copiar archivos del host en la imagen del contenedor, la instrucción ADD también puede copiar archivos de una ubicación remota con una especificación de dirección URL.

El formato de la instrucción ADD es similar al siguiente:

ADD <source> <destination>

Si el origen o el destino incluyen espacios en blanco, escribe la ruta de acceso entre corchetes y comillas dobles:

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

Consideraciones sobre el uso ADD con Windows

En Windows, el formato de destino debe usar barras diagonales. Por ejemplo, las siguientes son instrucciones ADD válidas:

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

Mientras tanto, el formato siguiente con barras diagonales inversas no funcionará:

ADD test1.txt c:\temp\

Además, en Linux, la instrucción ADD expandirá los paquetes comprimidos al copiarlos. Esta funcionalidad no está disponible en Windows.

Ejemplos del uso de ADD con Windows

En el ejemplo siguiente se agrega el contenido del directorio de origen a un directorio denominado sqllite en la imagen del contenedor:

ADD source /sqlite/

En el ejemplo siguiente se agregan todos los archivos que comienzan por "config" al directorio c:\temp de la imagen del contenedor.

ADD config* c:/temp/

En el ejemplo siguiente se descargará Python para Windows en el directorio c:\temp de la imagen del contenedor.

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

Para obtener información detallada sobre la instrucción ADD, consulta la referencia sobre ADD.

WORKDIR

La instrucción WORKDIR establece un directorio de trabajo para otras instrucciones de Dockerfile, como RUN y CMD, y también el directorio de trabajo para ejecutar instancias de la imagen del contenedor.

El formato de la instrucción WORKDIR es similar al siguiente:

WORKDIR <path to working directory>

Consideraciones sobre el uso WORKDIR con Windows

En Windows, si el directorio de trabajo incluye una barra diagonal inversa, debe llevar un símbolo de escape.

WORKDIR c:\\windows

Ejemplos

WORKDIR c:\\Apache24\\bin

Para obtener información detallada sobre la instrucción WORKDIR, consulta la referencia sobre WORKDIR.

CMD

La instrucción CMD establece que el comando predeterminado se ejecutará al implementar una instancia de la imagen del contenedor. Por ejemplo, si el contenedor va a hospedar un servidor web NGINX, CMD puede incluir instrucciones para iniciar el servidor web con un comando como nginx.exe. Si se especifican varias instrucciones CMD en un archivo Dockerfile, solo se evalúa la última.

El formato de la instrucción CMD es similar al siguiente:

# exec form

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

# shell form

CMD <command>

Consideraciones sobre el uso CMD con Windows

En Windows, las rutas de acceso de archivo que se especifican en la instrucción CMD deben usar barras diagonales o incluir barras diagonales inversas de escape \\. Las siguientes son instrucciones CMD válidas:

# exec form

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

# shell form

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

Sin embargo, el siguiente formato sin las barras diagonales adecuadas no funcionará:

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

Para obtener información detallada sobre la instrucción CMD, consulta la referencia sobre CMD.

Carácter de escape

En muchos casos, las instrucciones de Dockerfile tendrán que abarcar varias líneas. Para hacerlo, puedes usar un carácter de escape. El carácter de escape predeterminado para Dockerfile es una barra diagonal inversa \. Sin embargo, dado que la barra diagonal inversa es también un separador de ruta de acceso de archivos en Windows, su uso para abarcar varias líneas puede causar problemas. Para solucionar este problema, puedes usar una directiva de analizador para cambiar el carácter de escape predeterminado. Para más información sobre las directivas de analizador, consulta Directivas de analizador.

En el ejemplo siguiente se muestra una instrucción RUN individual que abarca varias líneas en la que se usa el carácter de escape predeterminado:

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 el carácter de escape, coloque una directiva del analizador de escape en la primera línea de la instrucción Dockerfile. Puedes ver como se hace en el ejemplo siguiente.

Nota

Solo hay dos valores que pueden utilizarse como caracteres de escape: \ y `.

# 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 más información sobre la directiva del analizador de escape, consulta Directiva del analizador de escape.

PowerShell en Dockerfile

Cmdlets de PowerShell

Pueden ejecutarse cmdlets de PowerShell en un archivo Dockerfile con la operación RUN.

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

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

Llamadas de REST

El comando Invoke-WebRequest de PowerShell puede resultar útil al recopilar información o archivos de un servicio web. Por ejemplo, si compilas una imagen que incluye Python, puedes establecer $ProgressPreference en SilentlyContinue para lograr descargas más rápidas, tal como se muestra en el ejemplo siguiente.

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

Nota

Invoke-WebRequest también funciona en Nano Server.

Otra opción para usar PowerShell para descargar archivos durante el proceso de creación de la imagen es usar la biblioteca .NET WebClient. Esto puede aumentar el rendimiento de descarga. En el ejemplo siguiente se descarga el software de Python mediante la 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

Nota

Nano Server no admite actualmente WebClient.

Scripts de PowerShell

En algunos casos, puede ser útil copiar un script en los contenedores que se usan durante el proceso de creación de la imagen y después ejecutarlo desde dentro del contenedor.

Nota

Esto limitará el almacenamiento en caché de las capas de la imagen y reducirá la legibilidad del archivo Dockerfile.

En este ejemplo se copia un script de la máquina de compilación en el contenedor mediante la instrucción ADD. Este script después se ejecuta con la instrucción 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

Compilación de Docker

Una vez que se ha creado un archivo Dockerfile y se ha guardado en el disco, se puede ejecutar docker build para crear la nueva imagen. El comando docker build toma varios parámetros opcionales y una ruta de acceso al archivo Dockerfile. Para obtener documentación completa sobre la compilación de Docker, incluida una lista de todas las opciones de compilación, consulta la referencia de compilación.

El formato del comando docker build es similar al siguiente:

docker build [OPTIONS] PATH

Por ejemplo, el comando siguiente creará una imagen denominada "iis".

docker build -t iis .

Cuando se inicie el proceso de compilación, la salida indicará el estado y devolverá los errores que se produzcan.

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

El resultado es una nueva imagen del contenedor, que en este ejemplo se denomina "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

Lecturas y referencias adicionales