🐋
Apuntes Sistemas
  • ⚓Presentación
  • 📊Sistemas y Servidores
    • Personalizar el prompt de Windows
    • Utilidad de manejo de apps para Windows
    • PRACTICA: Arranque dual Windows y Ubuntu
    • 🚧SysLinuxOS: el SO para ASIX
    • Comandos Linux
      • PRACTICA - Ejercicio de práctica comandos
      • 🚧Instalación de paquetes
      • Apuntes Linux: blue/red team
      • Ejemplos de bash
      • Listado de comandos de Linux
    • Comandos Windows
      • 🚧Apuntes Powershell
      • Bucles FOR con batch
      • Scripts de práctica de Windows
    • Prácticas con Windows 10
    • Configuración de netplan
    • Terminal shell
      • SSH
      • 🚧Ghostty
      • 🚧Warp: la terminal inteligente
      • tmux: paneles de terminal
      • Tabby: Mejorar terminal
      • Conexión SSH en red NAT con VirtualBox
      • TheFuck!: Corrección de comandos
      • Wave: Mejorar terminal Linux
      • 🚧Registros de sesiones
    • Instalación manual de Wordpress en CDMON
    • 🏗️Proxmox
    • 🚧TrueNAS
    • Docker
      • Instalación de Docker
      • Dockerfiles
      • Volúmenes de docker
      • Deployment web con Docker con ejemplos
        • 🚧PRACTICA: Node.js con docker
      • Docker Compose
        • Ejemplo 1: Implantación de Wordpress
        • Ejemplo 2: Implementación de servidor con Nginx, Flask y mySQL
        • Ejemplo 3: Implantación de onlyoffice
        • 🚧Ejemplo 4: Passbolt
        • 🚧PRACTICA: Creando una web de emulación de juegos con docker-compose
      • Monitorización con Grafana en Docker
      • Pi-hole con docker
      • Actividad clase: Deployment app
      • Proyectos self-hosted de docker
    • 🚧Ansible
      • Configuración de laboratorio de ansible
    • 🚧Monitorización de servicios y redes
      • Servicios y cronjobs
      • 1Panel
      • 🚧WatchYourLAN
      • 🚧Uptime-kuma
      • 🚧Netdata
      • 🚧Prometheus + Grafana + Loki
    • LDAP
      • 🚧Gestión gráfica de LDAP
      • Carpetas compartidas NFS
      • PRACTICA: Infraestructura LDAP
  • 🗃️Servicios
    • 🚧Servidor hosting público
    • DHCP
      • DHCP con Ubuntu
      • 🦖DHCP & DNS script
      • DHCP con Alpine
        • Alpine - configuración de red
    • DNS
      • 😡Comprobación DNS
      • Script para enumeración DNS
      • DNS con ubuntu server
      • 🏗️DNSmasq
      • 🚧Securizar servidor DNS
    • Web
      • IIS con Windows server
      • Apache
        • Instalación de LAMP en Ubuntu
          • Prueba de servidor LAMP
          • 🚧Configuración de seguridad de Ubuntu
          • Creación de un VirtualHost en LAMP
          • Creación de varios VirtualHosts en LAMP
          • 🚧Instalación por script de LAMP
        • Aplicaciones con LAMP
          • Instalación de WP en entorno LAMP
          • 🚧Instalación de MantisBT en LAMP
            • 👷Guía de MantisBT
          • 🚧Instalación de QDPM con LAMP
      • Nginx
        • Virtualhosts
        • Instalando Wordpress en nginx
      • 👷MEAN stack
      • 👷‍♂️Caddy
      • 🚧Plesk
      • 🚧Ajenti -Web interface
    • 🏗️Proxy
      • Nginx como proxy inverso y balanceador
      • 🚧Zoraxy
    • Mailing
      • 🚧Servidor Mail con cloudfare
      • 🚧Reenvío de correos de root
      • 🚧Roundcube como MUA
      • Comprobación ESMTP
      • 🚧Seguridad en mailing
      • 🚧Mailhog
    • 🏗️File transfer
      • 🚧FTP
      • Git
    • Sistemas de comunicación instantánea
      • Comunicación mediante CLI
      • Ejabberd - XMPP
        • 🚧Ejabberd con docker
      • 🚧Openfire - XMPP
      • 🚧Comunicaciones servidor-móvil
    • 🏗️Multimedia services
      • Stremio
      • Ver anime por CLI
      • Jellyfin
      • 🚧HLS sobre Apache
      • 🚧Servicio autohospedado de videoconferencia
      • 🚧Morphos: Conversor docs
      • 🚧Reproductores de música en CLI
      • 🚧Icecast - música en streaming
      • 🚧RTMP-HLS server
      • 🚧Guacamole
  • 🖱️Hardware
    • 🚧Identificando conectores
    • Curso de electrónica analógica
    • Alcanzar los 3200MHz con la RAM
    • Calculadora de cuellos de botella
    • 🚧PXE: Bootear sistemas en red
    • 🚧PRÁCTICA - Clonación de disco con Clonezilla
    • Logitech iFixit
  • 🕸️Redes
    • Apuntes IPv4 Alina
    • ¿Cómo diferenciar tantos elementos de red?
    • 🚧IPv6
    • PRÁCTICA - Subneteo con IPcalc en Linux
    • PRÁCTICA - Comandos de red en Windows
    • 🚧PRÁCTICA - Comandos de red en Linux
    • Herramientas de red
      • 🚧TCPDump: analizado de paquetes en red
      • PRÁCTICA - Netsh
      • 🚧PRÁCTICA - mtr.ping.pe
      • 🚧Netcat
    • Wireshark
    • VPN y escritorio remoto
      • Comunicación punto a punto con ngrok
      • 🚧VPN
    • Escaneo de red
      • PRÁCTICA - Mapeado de red con Draw.io
      • 🚧PRÁCTICA - Nmap/Zenmap
    • Redes inalámbricas
      • Wi-fi
        • 🚧PRÁCTICA - Configuración de router
        • 🚧PRÁCTICA - Como hacer un Wifi Heatmap
        • 🚧Seguridad de redes inalámbricas
        • PRÁCTICA - Crackear la contraseña del Wifi con WPA/WPA2
    • PRÁCTICA - Usar SSH en Cisco packet tracer
  • 🛑Ciberseguridad
    • 🚧Securizando un servidor Linux
      • Protégete de ataques de fuerza bruta con Fail2ban
      • Firewall
        • UFW (uncomplicated firewall)
          • GUFW - Interfaz gráfica de ufw
        • 🚧IPTables
        • 🚧PFsense
          • 🚧DMZ con PFsense
      • 🚧Passbolt: gestor de contraseñas autohospedado
      • 🚧Hashes y encriptación
      • 🚧Certificados SSL/TLS
      • Copias de seguridad
    • 🚧Alerta de escaneo de puertos
    • 🚧Google dorks
    • 🚧Enumeración DNS
    • Comandos destructivos de linux
    • Webs enseñanza cyber
    • Wireless Pentesting CheatSheet Github
    • The password game!
    • Personal Security Checklist
  • 🔌Arduino
    • Termómetro e higrómetros digitales y online con Arduino
    • Construyendo un coche multipropósito
      • Multi
      • Montaje del auto
    • Arduino con Sigfox para IoT
    • 10 proyectos de Arduino
  • 📚Recursos y libros
    • Media library: libros varios
    • Herramientas básicas de sysadmin
  • 🌍Sostenibilidad y digitalización
    • Portfolio curso digitalización MOOC
    • 🚧Explotación de recursos por IA
    • 🚧Nuevas tecnologias y comunicaciones
    • 🚧Enlaces sobre Inteligencia artificial
Con tecnología de GitBook
En esta página
  1. Sistemas y Servidores
  2. Docker

Dockerfiles

Vamos a probar Docker con un ejemplo con php y dockerfiles con mariaDB.

AnteriorInstalación de DockerSiguienteVolúmenes de docker

Última actualización hace 3 meses

Un Dockerfile es un archivo de texto que contiene una serie de instrucciones para construir una imagen de Docker. Estas instrucciones describen cómo configurar un entorno desde cero (o a partir de una imagen base) para ejecutar una aplicación específica. Es la base para automatizar la creación de imágenes Docker.

Conceptos clave

  • Imagen de Docker: Una imagen es una plantilla que contiene todo lo necesario para ejecutar una aplicación: sistema operativo, dependencias, librerías, y la propia aplicación.

  • Contenedor de Docker: Es una instancia ejecutable de una imagen, funcionando de manera aislada.

El Dockerfile es donde defines cómo se crea la imagen, paso a paso.


Cómo funciona un Dockerfile

Cuando ejecutas un comando como docker build, Docker:

  1. Lee el Dockerfile línea por línea.

  2. Construye una imagen Docker siguiendo las instrucciones del archivo.

  3. Crea una capa en la imagen por cada instrucción del Dockerfile:

    • Estas capas se almacenan en caché para optimizar futuras construcciones.

    • Si el contenido de una capa no cambia, se reutiliza en lugar de reconstruirse.

Finalmente, obtienes una imagen que puedes usar para lanzar contenedores.


Estructura básica de un Dockerfile

Un Dockerfile tiene una serie de instrucciones clave que definen cómo construir la imagen. Aquí está un desglose de las más comunes:

1. Especificar una imagen base

La imagen base es el punto de partida para tu imagen. Por ejemplo:

FROM python:3.10-slim

Esto indica que usarás la imagen oficial de Python 3.10 en su versión minimalista como base.

2. Agregar metadatos (opcional)

Puedes agregar información sobre la imagen usando etiquetas como:

LABEL maintainer="tu_email@example.com"
LABEL version="1.0"
LABEL description="Esta imagen ejecuta una aplicación Flask."

3. Copiar archivos al contenedor

Para copiar archivos desde tu máquina al contenedor:

COPY app/ /app/

Esto copia el contenido de la carpeta app/ en tu máquina al directorio /app/ dentro de la imagen.

4. Ejecutar comandos durante la construcción

Puedes instalar dependencias, descargar archivos o configurar el sistema operativo usando RUN:

RUN apt-get update && apt-get install -y libpq-dev
RUN pip install flask mysql-connector-python

Cada comando crea una nueva capa en la imagen.

5. Configurar el directorio de trabajo

El comando WORKDIR establece el directorio en el que se ejecutarán los comandos posteriores:

WORKDIR /app

6. Definir variables de entorno

Puedes configurar variables de entorno dentro del contenedor:

ENV FLASK_ENV=development

7. Exponer puertos

Indica qué puertos estarán disponibles para conexiones externas:

EXPOSE 5000

8. Definir el comando de inicio

Usa CMD para definir el comando que se ejecutará cuando se inicie el contenedor:

CMD ["flask", "run", "--host=0.0.0.0"]

O usa ENTRYPOINT si quieres que ciertos comandos sean fijos, permitiendo añadir parámetros adicionales al ejecutar el contenedor:

dockerfileCopiar códigoENTRYPOINT ["python"]
CMD ["app.py"]

A continuación tienes todos los argumentos que puede admitir un dockerfile:

#1. Imagen de base
FROM <base_image>:<tag>
#Ejemplo: FROM Ubuntu:20.04

#2. Metadatos
LABEL <key>=<value> ...
#Ejemplo: LABEL mantenimiento="you@ejemplo.com"

# 3. Instalar dependencias
RUN <command> && <command>
# Ejemplo: RUN apt-get update && apt-get install -y curl

# 4. Establecer el directorio de trabajo
WORKDIR /path/to/workdir
# Ejemplo: WORKDIR /app

# 5. Copiar archivos al contenedor:
COPY <src> <dest>
# Ejemplo: COPY . /app
# OR
ADD <src> <dest>
# Ejemplo: ADD https://ejemplo.com/file.tar.gz /app/

# 6. Establecer las variables de entorno
ENV <key>=<value>
# Ejemplo: ENV NODE_ENV=produccion

# 7. Abrir puertos
EXPOSE <port>
# Ejemplo: EXPOSE 8080

# 8. Especificar comando por defecto:
CMD ["executable", "param1", "param2"]
# Ejemplo: CMD ["npm", "start"]
# OR
ENTRYPOINT ["executable", "param1", "param2"] 
#Ejemplo: ENTRYPOINT ["python", "app.py"]

# 9. Añadir volúmenes:
VOLUME ["/path/to/dir"]
# Ejemplo: VOLUME ["/data"]

# 10. Definir argumentos por defecto:
ARG <name>[=<default value>] 
# Ejemplo: ARG VERSION=1.0.0

# 11. Revisión del rendimiento del sistema
HEALTHCHECK [OPTIONS] CMD <command>
# Ejemplo: HEALTHCHECK --interval=30s --timeout=10s \
# CMD curl -f http://localhost/health || exit 1

# 12. Establecer usuario:
USER <username_or_uid>
# Ejemplo: USER node

#13. Stop Signal
STOPSIGNAL <signal>
# Ejemplo: STOPSIGNAL SIGTERM

# 14. Comando de la shell
RUN <command>
# Ejemplo: RUN echo "Hello World"

# 15. Ejecutar desde comando:
RUN ["executable", "param1", "param2"]
# Ejemplo: RUN ["python", "app.py"]

#16. Especificar el tipo de shell:
SHELL ["executable", "param1"]
#Ejemplo: SHELL ["/bin/bash", "-c"]

Ejemplo) Dockerfile con MariaDB

Para evitar que el comando que se escribe en el Para mitigar estos errores, se puede crear un archivo llamado Dockerfile con la configuración que queramos tener en el contenedor:

Vamos a revisar como funciona Dockerfile creando un contenedor de MySQL.

sudo nano Dockerfile

Dentro de este archivo escribiremos:

## MySQL 8
## Imagen base
FROM mariadb:latest
FROM mysql:latest

## Variables de entorno. Configuración inicial de MySQL 8
ENV MYSQL_ROOT_PASSWORD=1234
ENV MYSQL_DATABASE=wpalex
ENV MYSQL_USER=alex
ENV MYSQL_PASSWORD=P@ssw0rd
## Puerto donde se expondrá el Servidor de Bases de Datos
EXPOSE 3306
## Directorio del Contenedor que necesita persistencia
VOLUME /var/lib/docker/volumes/wordpress-db/_data

## MySQL 8 - Usando MySQL como base
FROM mysql:latest

## Variables de entorno - Configuración inicial de MySQL
ENV MYSQL_ROOT_PASSWORD=1234
ENV MYSQL_DATABASE=wpalex
ENV MYSQL_USER=alex
ENV MYSQL_PASSWORD=P@ssw0rd

## Puerto donde se expondrá el Servidor de Bases de Datos
EXPOSE 3306

## Directorio del Contenedor que necesita persistencia
VOLUME /var/lib/mysql

Donde:

  • FROM: Le indica la imagen que se va a usar en el contenedor, en este caso MySQL oficial en última versión

  • ENV: Hace referencia a variables de entorno del contenedor que se configurarán al iniciarse.

  • EXPOSE: Indica el puerto en el que será visible, en este caso el de por defecto de mysql. Este es importante para conectar luego las apps cliente.

A continuación tienes algunos parámetros más comunes de un fichero dockerfile:

Parámetro
Ejemplo
Descripción

FROM

FROM mysql

Indica la imagen base desde la que se construye.

ENV

ENV HOME=/home/app

WORKDIR

WORKDIR /home/app

Indica el directorio de trabajo para los siguientes comandos.

COPY

COPY *.txt /doc/

Copia archivos desde el anfitrión al contenedor

VOLUME

VOLUME /myvol1

Crea un punto de montaje accesible por otros contenedores.

RUN

RUN npm install

Ejecuta un comando en el contenedor.

EXPOSE

EXPOSE 3000

Abre un puerto para ese contenedor.

ARG

ARG NAME

Indicamos el argumento que deseamos para nuestra imagen. Con esto le decimos: esperará un argumento personalizado al momento de crear la imagen.

  1. Ahora toca construir el contenedor en si según los parámetros definidos, para ello ejecutamos:

docker build -t alexdb:latest .

Al final del proceso obtendremos un codigo que será el ID de la imagen de docker o puedes listar las imágenes como hemos visto antes.

Al ejecutar la imagen en un contenedor se puede verificar la versión de MySQL y, como tenemos los datos de conexión, entrar a verificar las bases de datos creadas por defecto. Ejecute el comando sustituyendo [IMAGE ID] por el valor que tiene su imagen:

docker run -d [IMAGE ID] 

Esto lanzará el docker en segundo plano.

  1. Para hacer la conexión a la base de datos tendrá que ejecutar lo siguiente:

docker exec -it [CONTAINER ID] sh

Tras acceder al shell del contenedor, ya puedes hacer pequeñas comprobaciones:

mysql --version
mysql -u root -p

El segundo comando te permitirá acceder mediante el usuario root al CLI de mysql teniendo que poner la contraseña antes descrita. Si se realiza correctamente la conexión, se mostrará una información de bienvenida.

  1. Para comprobar las bases de datos que están creadas, incluida la configurada en el Dockerfile, se puedes escribir:

show databases;

Referencia:

Creamos el archivo dockerfile en una carpeta recién creada que queramos como la que hemos creado en la guía de donde tenemos creado el volumen llamado "wordpress-db":

VOLUME: Se crea una zona fuera del contenedor para almacenar el contenido de la ruta escrita. Esto se hace para almacenar los datos (de mysql en este caso) incluso si se borra o para el contenedor. Tienes la explicación de donde ha salido de la .

Añade una variable de entorno. Las variables de entorno las puedes encontrar en las páginas respectivas del .

Docker labs:

volúmenes
guía
https://labs.play-with-docker.com/
Docker hub
📊
Page cover image
Estructura de un dockerfile