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