Dockerfile - Crear imagen desde cero¶
Info oficial -> aquí
Para poder crear una imagen desde otra con todo lo que necesita, pero de manera más cómoda, lo que se usan son unos ficheros de texto llamados Dockerfile. Por defecto los ficheros se tienen que llamar así, aunque se pueden cambiar.
Estructura / Directivas del Dockerfile¶
Este fichero tiene ciertas palabras clave o directivas:
FROM¶
Imagen base en la que se va a basar la nueva.
- Es la primera directiva del
Dockerfile. - Puede haber varias
FROMpara usar lo que se llama el Multi-Stage-Build. - Puede ir precedida de la directiva
ARG
ARG CODE_VERSION=latest
FROM base:${CODE_VERSION}
CMD /code/run-app
FROM extras:${CODE_VERSION}
CMD /code/run-extras
LABEL¶
Es para añadir metadata a la imagen (autor, mantenedor, versión, etc).
- Puede haber más de una
LABELporDockerfile. - Consiste en un conjunto de clave-valor, y pueden ir varias por línea.
MAINTAINER-> Creador de la imagen, pero está deprecated. UsarLABEL.
RUN¶
Comandos a ejecutar ANTES de ser creada (por ejemplo, paquetes a instalarle a la imagen base).
- Puede haber varias directivas
RUNen unDockerfile. - Se debe usar comillas dobles
"no comillas simples'.
COPY¶
Copia ficheros locales a la imagen.
COPY <src> <dest>
COPY <src1> <src2> ... <dest>
COPY [--chown=<user>:<group>] <src> ... <dest>
COPY [--chown=<user>:<group>] ["<src>", ... "<dest>"]
- Puede haber varios
COPYporDockerfile. --chownsolo se puede usar en Linux (en Windows no).
ADD¶
Hace lo mismo que COPY, pero además solo copia ficheros locales. Puedes copiar contenido desde una URL, o si el fichero está comprimido, al usar ADD lo descomprime.
ADD <src> <dest>
ADD <src1> <src2> ... <dest>
ADD [--chown=<user>:<group>] <src> ... <dest>
ADD [--chown=<user>:<group>] ["<src>", ... "<dest>"]
- Puede haber varios
ADDen elDockerfile. --chownsolo sirve en Linux (en Windows no va).- Se pueden usar ciertas reglas en
<src>y<dest>como*.py(todos los ficheros que acaben en .py).
ENV¶
Variable de entorno.
- Puede haber varias
ENVporDockerfile. - Si alguna
ENVes igual que algunaARG, la sobreescribe (ENV>ARG).
WORKDIR¶
Directorio de trabajo de la imagen.
- Puede haber varios
WORKDIRdentro delDockerfile(aunque no tiene sentido). - Sirve para definir el directorio con las directivas
RUN,CMD,ENTRYPOINT,COPY,ADD. - Este ejemplo hace que el directorio de trabajo sea
/a/b/c
Que se podría poner de manera más simple con
EXPOSE-> Exponer por defecto un puerto del contenedor.
- Puede haber varios
EXPOSEporDockerfile. - Si no se especifica el protocolo, por defecto toma
tcp, pero si quieresudptienes que especificarlo. -
Si quisieras que permita los dos protocolos, se debe incluir en dos líneas.
-
Con la opción
-pse sobreescribe lo del Dockerfiledocker run -p 80:80/tcp 80:80/udp .... - Esto se gestiona con
docker network. USER-> Sirve para indicar dentro delDockerfileun usuario.
- Puede haber varios
USERdentro delDockerfile. - Son para ejecutar
RUN,CMDoENTRYPOINTcon un usuario especifico, en lugar de root. - El usuario por defecto de un
Dockerfilees root. VOLUME-> Para persistencia de datos, indicamos al contenedor donde almacenar sus datos en un directorio del Docker Host (nuestra máquina).
- Esto es un concepto más avanzado y se ve en su propia sección.
- ENTRYPOINT ->
CMD-> Acción por defecto al crear el contenedor.
- Solo puede haber una CMD por Dockerfile.
.dockerignore - Descartar ficheros para crear una imagen¶
El .dockerignore equivale al .gitignore de git.
Es un fichero donde indicarle al Dockerfile que archivos y/o directorios no cargar en la imagen.
docker build - Construir imagen desde el Dockerfile¶
Info oficial -> aquí
Para crear la imagen con un Dockerfile que se llama Dockerfile se jecuta
Si queremos usar otro fichero con otro nombre como Dockerfile hay que usar la opción -f
Se recomienda usar siempre la opción -t para asignarle un nombre y opcionalmente un tag a la imagen. Si no se especifica el tag, docker pone por defecto latest
Se le puede indicar el path donde está el Dockerfile, y este path puede ser incluso una url de un repo git. Se recomienda usar
Dangling images - Imágenes huérfanas / colgadas¶
Si al construir varias imágenes del mismo Dockerfile, estas se llaman igual (porque no hemos especificado nombres y tags distintos), solo la más nueva tiene el nombre y todas las demás quedan huérfanas. Al usar docker images vemos come en su REPOSITORY pone <none> y en TAG pasa igual. Por eso HAY QUE USAR TAGS.
La forma de ver todas estas imágenenes colgadas es con
Lo lógico es borrar todas estas imágenes, para ello añadimos a la sentencia anterior -q para ver solo los ids y luego usar el comando docker rmi. Una forma automática de hacer esto es
Multi-Stage-Build¶
Es probable que a veces necesitemos usar algo (fichero, carpetas, ...) de alguna imagen para poder usarlo en otra. Tendríamos dos opciones:
- Crear una imagen con "las dos imagenes dentro", es decir, crear una imagen más pesada.
- Generar los recursos en una imagen temporal y copiarlos a la imagen final -> Multi-Stage-Build.
La forma de hacer el paso 2. consiste en usar varios FROM dentro del Dockerfile. A cada FROM se asigna un alias y para poder llamar algo de esa imagen usamos la opción --from=<alias>. El último FROM es con el que se va a construir la imagen, pero los anteriores los ejecuta y podemos copiar los ficheros en las instrucciones a partir del último FROM. Un ejemplo
FROM <imagen-que-genera-fichero> AS <alias-de-ayuda>
# Operaciones
FROM <imagen-final>
COPY --from=<alias-de-ayuda> <fichero-src-en-la-imagen-de-arriba> <fichero-dest-en-mi-imagen-final>
La imagen base va a ser <imagen-final>, y todas las demás no entran dentro, pero si se generan para poder hacer el COPY.
Buenas prácticas Dockerfile¶
Info oficial -> aquí
- Contenedor efímero -> Fácilmente destruible
- Un servicio por contenedor
- Crear un .dockerignore para evitar archivos pesados
- Cuantas menos capas mejor:
- Argumentos largos separados con
\. - Varios argumentos en una sola capa (en vez de muchas capas).
- Argumentos largos separados con
- No instalar paquetes innecesarios (solo el servicio).
- Usar Multi-Stage-Build.
- Usar
LABELpara documentar (versiones, descripciones, etc).