Docker es una virtualización a nivel de sistema operativo destinada principalmente a desarrolladores y administradores de sistemas. Docker facilita la creación e implementación de aplicaciones en un entorno aislado.
Un Dockerfile es un script que contiene colecciones de comandos e instrucciones que se ejecutarán automáticamente en secuencia en el entorno de la ventana acoplable para crear una nueva imagen de la ventana acoplable.
En este tutorial, le mostraremos cómo crear su propia imagen de Docker con un Dockerfile. Explicaremos los detalles relacionados con Dockerfile para permitirle crear su propia imagen de Docker.
Requisitos previos
Para esta guía, usaremos Ubuntu 20.04 con 1 GB de RAM, 25 GB de espacio libre en disco y 2 CPU. Además, usaremos Ubuntu 20.04 como imagen base para crear la imagen Docker personalizada.
Introducción al comando Dockerfile
Un Dockerfile es un script que contiene todos los comandos para crear una imagen de Docker. El Dockerfile contiene todas las instrucciones que se usarán para crear la imagen de Docker con el comando 'docker build'.
Antes de crear su primer Dockerfile, debe familiarizarse con las instrucciones de Dockerfile. A continuación, algunas instrucciones de Dockerfile que debe conocer.
DE
Establezca la imagen base para la nueva imagen que desea crear. La instrucción FROM inicializará la nueva etapa de compilación y debe ubicarse en la parte superior del Dockerfile.
ETIQUETA
Con esta instrucción, puede agregar información adicional sobre su imagen de Docker, como la versión, la descripción, el responsable del mantenimiento, etc. La instrucción LABEL es un par clave-valor que le permite agregar varias etiquetas y valores de varias líneas.
CORRE
Esta instrucción solía ejecutar el comando durante el proceso de construcción de la imagen de la ventana acoplable. Puede instalar paquetes adicionales necesarios para sus imágenes de Docker.
AÑADIR
La instrucción ADD se usa para copiar archivos, directorios o archivos remotos desde la URL a sus imágenes de Docker, desde 'src' a la ruta absoluta 'dest'. Además, puede configurar la propiedad predeterminada de su archivo.
ENV
La instrucción ENV se usa para definir una variable de entorno que se puede usar durante la etapa de compilación y también se puede reemplazar en línea en muchos.
CMD
La instrucción CMD se utiliza para definir el comando predeterminado que se ejecutará al ejecutar el contenedor. Y el Dockerfile solo debe contener una instrucción CMD, y si hay varios CMD, se ejecutará la última instrucción CMD.
EXPONER
Esta instrucción se usa para exponer el puerto del contenedor en los puertos de red específicos en tiempo de ejecución. El protocolo predeterminado expuesto es TCP, pero puede especificar si es TCP o UDP.
ARG
La instrucción ARG se usa para definir una variable que el usuario puede pasar en el momento de la construcción. Puede usar esta instrucción en el 'comando de compilación' de la ventana acoplable durante el tiempo de compilación usando la opción '--build-arg variable=value' y se puede pasar a través de Dockerfile. Además, puede usar múltiples ARG en el Dockerfile.
PUNTO DE ENTRADA
La instrucción ENTRYPOINT se utiliza para definir el primer comando predeterminado que se ejecutará cuando se ejecute el contenedor. Defina el comando para iniciar su aplicación con la instrucción ENTRYPOINT.
DIR.TRABAJO
La instrucción WORKDIR se usa para definir el directorio de trabajo predeterminado de su imagen de Docker. Las instrucciones RUN, CMD, ENTRYPOINT y ADD siguen a la instrucción WORKDIR. Puede agregar varias instrucciones WORKDIR en su Dockerfile y, si no existe, se creará automáticamente.
USUARIO
La instrucción USER se utiliza para definir el usuario predeterminado o gid al ejecutar la imagen. EJECUTAR, CMD y PUNTO DE ENTRADA siguen las instrucciones de USUARIO en el Dockerfile.
VOLUMEN
El anuncio de instrucciones de VOLUMEN utilizado para habilitar el acceso/directorio vinculado entre el contenedor y la máquina host.
Ahora, comencemos a crear el primer Dockerfile.
Paso 1:instalar Docker en Ubuntu 20.04
Antes de crear un Dockerfile, instalaremos el Docker en nuestro sistema Ubuntu 20.04, que está disponible de forma predeterminada en el repositorio de Ubuntu FocalFossa.
Actualice la lista de todos los paquetes en el repositorio de Ubuntu e instale Docker usando el comando apt a continuación.
sudo apt update
sudo apt install docker.io
Una vez completada toda la instalación, inicie el servicio Docker y agréguelo al inicio del sistema.
systemctl start docker
systemctl enable docker
Ahora verifique el servicio Docker usando el siguiente comando.
systemctl status docker
El servicio Docker está funcionando en Ubuntu 20.04.
A continuación, ejecute el siguiente comando docker para asegurarse de que la instalación sea correcta.
docker run hello-world
A continuación se muestra el resultado que obtendrá.
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
Como se puede ver, recibe el mensaje Hello World de Docker y la instalación de Docker en Ubuntu 20.04 se completó con éxito.
Paso 2:crear Dockerfile y otras configuraciones
En este paso, le mostraremos cómo crear una imagen de Docker personalizada para su aplicación utilizando Dockerfile. Crearemos una nueva imagen de Docker personalizada basada en la imagen de Ubuntu 20.04, para los servicios PHP-FPM y Nginx, luego ejecutaremos el nuevo contenedor con un simple script phpinfo.
Primero, cree un nuevo directorio de proyecto y cree un Dockerfile vacío.
mkdir -p nginx-image; cd nginx-image/
touch Dockerfile
Ahora edite el script 'Dockerfile' usando su propio editor (para este ejemplo estamos usando vim).
vim Dockerfile
En la parte superior de la línea, agregue la imagen base de Ubuntu 20.04 usando la instrucción FROM como se muestra a continuación.
#Download base image ubuntu 20.04
FROM ubuntu:20.04
Ahora agregue información detallada sobre la imagen personalizada usando la instrucción LABEL.
# LABEL about the custom image
LABEL maintainer="[email protected]"
LABEL version="0.1"
LABEL description="This is custom Docker Image for \
the PHP-FPM and Nginx Services."
Para la instalación de paquetes apt, omitiremos cualquier paso interactivo posterior a la instalación utilizando la variable de entorno 'DEBIAN_FRONTEND=noninteractive'.
# Disable Prompt During Packages Installation
ARG DEBIAN_FRONTEND=noninteractive
Luego, ejecute el comando 'apt update' antes de instalar cualquier paquete.
# Update Ubuntu Software repository
RUN apt update
Ahora instale los paquetes Nginx, PHP-FPM y supervisor. Una vez completada toda la instalación, elimine la memoria caché de todos los paquetes para reducir el tamaño de la imagen personalizada.
# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt install -y nginx php-fpm supervisor && \
rm -rf /var/lib/apt/lists/* && \
apt clean
Defina una nueva variable de entorno que se pueda pasar a la imagen personalizada.
#Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/7.4/fpm/php.ini
ENV nginx_conf /etc/nginx/nginx.conf
ENV supervisor_conf /etc/supervisor/supervisord.conf
Ahora copie la configuración predeterminada de Nginx a la variable 'nginx_vhost', reemplace la configuración de PHP 'cgi.fix_pathinfo=1' con 'cgi.fix_pathinfo=0' en el archivo de configuración php.ini, luego agregue la opción 'daemon off' al variable predeterminada 'nginx_conf'.
# Enable PHP-fpm on nginx virtualhost configuration
COPY default ${nginx_vhost}
RUN sed -i -e 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' ${php_conf} && \
echo "\ndaemon off;" >> ${nginx_conf}
Copie la configuración supervisada personalizada en la variable 'supervisor_conf'.
#Copy supervisor configuration
COPY supervisord.conf ${supervisor_conf}
Cree un nuevo directorio para el archivo sock PHP-FPM, cambie la propiedad del directorio raíz web '/var/www/html' y el directorio PHP-FPM '/run/php' al usuario predeterminado 'www-data'.
RUN mkdir -p /run/php && \
chown -R www-data:www-data /var/www/html && \
chown -R www-data:www-data /run/php
Defina el volumen de la imagen personalizada para que podamos montar todos esos directorios en la máquina host.
# Volume configuration
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]
Ahora agregue el script 'start.sh' y defina el comando de contenedor predeterminado usando la instrucción CMD como se muestra a continuación.
# Copy start.sh script and define default command for the container
COPY start.sh /start.sh
CMD ["./start.sh"]
Y por último, abra los puertos HTTP y HTTPS predeterminados en el contenedor mediante la instrucción EXPOSE.
# Expose Port for the Application
EXPOSE 80 443
Guardar y cerrar.
A continuación se muestra el script Dockerfile completo que acabamos de crear.
# Download base image ubuntu 20.04
FROM ubuntu:20.04
# LABEL about the custom image
LABEL maintainer="[email protected]"
LABEL version="0.1"
LABEL description="This is custom Docker Image for \
the PHP-FPM and Nginx Services."
# Disable Prompt During Packages Installation
ARG DEBIAN_FRONTEND=noninteractive
# Update Ubuntu Software repository
RUN apt update
# Install nginx, php-fpm and supervisord from ubuntu repository
RUN apt install -y nginx php-fpm supervisor && \
rm -rf /var/lib/apt/lists/* && \
apt clean
# Define the ENV variable
ENV nginx_vhost /etc/nginx/sites-available/default
ENV php_conf /etc/php/7.4/fpm/php.ini
ENV nginx_conf /etc/nginx/nginx.conf
ENV supervisor_conf /etc/supervisor/supervisord.conf
# Enable PHP-fpm on nginx virtualhost configuration
COPY default ${nginx_vhost}
RUN sed -i -e 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/g' ${php_conf} && \
echo "\ndaemon off;" >> ${nginx_conf}
# Copy supervisor configuration
COPY supervisord.conf ${supervisor_conf}
RUN mkdir -p /run/php && \
chown -R www-data:www-data /var/www/html && \
chown -R www-data:www-data /run/php
# Volume configuration
VOLUME ["/etc/nginx/sites-enabled", "/etc/nginx/certs", "/etc/nginx/conf.d", "/var/log/nginx", "/var/www/html"]
# Copy start.sh script and define default command for the container
COPY start.sh /start.sh
CMD ["./start.sh"]
# Expose Port for the Application
EXPOSE 80 443
A continuación, crearemos una nueva configuración adicional para Nginx, supervisord y el script start.sh.
La configuración de host virtual Nginx 'predeterminada' contendrá la sección para PHP-FPM. De hecho, puede ejecutar el script PHP utilizando la imagen personalizada sin ningún cambio.
Cree una nueva configuración de host virtual 'predeterminada' de Nginx con su editor.
vim default
Pegue la siguiente configuración en él.
server {
listen 80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.4-fpm.sock;
}
}
Guardar y cerrar.
A continuación, crearemos la configuración 'supervisrod.conf' que contiene el programa Nginx y PHP-FPM que se ejecutará automáticamente.
Cree el archivo 'supervisrod.conf' usando su editor.
vim supervisord.conf
Pegue la siguiente configuración en él.
[unix_http_server]
file=/dev/shm/supervisor.sock ; (the path to the socket file)
[supervisord]
logfile=/var/log/supervisord.log ; (main log file;default $CWD/supervisord.log)
logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB)
logfile_backups=10 ; (num of main logfile rotation backups;default 10)
loglevel=info ; (log level;default info; others: debug,warn,trace)
pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid)
nodaemon=false ; (start in foreground if true;default false)
minfds=1024 ; (min. avail startup file descriptors;default 1024)
minprocs=200 ; (min. avail process descriptors;default 200)
user=root ;
[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
[supervisorctl]
serverurl=unix:///dev/shm/supervisor.sock ; use a unix:// URL for a unix socket
[include]
files = /etc/supervisor/conf.d/*.conf
[program:php-fpm7.4]
command=/usr/sbin/php-fpm7.4 -F
numprocs=1
autostart=true
autorestart=true
[program:nginx]
command=/usr/sbin/nginx
numprocs=1
autostart=true
autorestart=true
Guardar y cerrar.
Ahora cree el script 'start.sh' usando t=su editor, contendrá el comando supervisado para comenzar.
vim start.sh
Pegue la siguiente configuración en él.
#!/bin/sh
/usr/bin/supervisord -n -c /etc/supervisor/supervisord.conf
Guardar y cerrar.
Haga que el script 'start.sh' sea ejecutable.
chmod +x start.sh
Como resultado, se ha creado toda la configuración para nuestra imagen de Docker personalizada, a continuación se muestran todas las configuraciones que hemos creado.
tree .
Ahora estamos listos para crear una nueva imagen personalizada basada en estas configuraciones.
Paso 3:crear un nuevo contenedor personalizado y ejecutar un nuevo
Para crear la imagen personalizada de Docker, vaya al directorio del proyecto 'nginx-image' y ejecute el comando 'docker build' como se muestra a continuación.
docker build -t nginx-image .
El comando descargará la imagen base de Ubuntu 20.04 y creará una nueva imagen personalizada con el nombre 'nginx-image.
Una vez que se complete todo el proceso, verifique la lista de imágenes Docker disponibles en su sistema usando el siguiente comando.
docker image ls
A continuación se muestra el resultado que obtendrá.
Como puede verse, se ha creado la nueva imagen personalizada de Docker 'nginx-image'.
A continuación, ejecutaremos el nuevo contenedor Docker basado en la 'imagen nginx'.
En su máquina local, cree un nuevo directorio llamado 'webroot' que se usará para almacenar todos los archivos web.
mkdir -p /webroot
Ahora cree un nuevo contenedor llamado contenedor de prueba usando el comando de ejecución de la ventana acoplable a continuación.
docker run -d -v /webroot:/var/www/html -p 8080:80 --name test-container nginx-image
- --name test-container nginx-image =Creamos un nuevo contenedor con el nombre 'test-container', basado en la imagen acoplable 'nginx-image'.
- -p 8080:80 =contenedor de contenedor de prueba que se ejecuta en el puerto 8080 en la máquina host.
- -v /webroot:/var/www/html =directorio /webroot en la máquina host reescribe el directorio /var/www/html en el contenedor.
Después de eso, verifique todos los contenedores en ejecución en su sistema usando el siguiente comando.
docker ps
A continuación se muestra el resultado que obtendrá.
Como resultado, el nuevo contenedor llamado 'test-container' basado en 'nginx-image' y expone el puerto 8080 está en funcionamiento.
Paso 4 - Prueba
Para asegurarnos de que el contenedor se ejecuta correctamente, crearemos un nuevo archivo index.html y phpinfo en el directorio raíz '/webroot' en la máquina host. Porque el directorio '/webroot' está montado en el directorio contenedor '/var/www/html'.
Cree el archivo index.html en el directorio '/webroot' usando el siguiente comando.
echo '<h1>Nginx and PHP-FPM 7.4 inside Docker Container with Ubuntu 20.04 Base Image</h1>' > /webroot/index.html
Ahora pruebe el acceso a su contenedor con el comando curl en el puerto 8080.
curl server-ip:8080
curl -I server-ip:8080
Como resultado, obtendrá la página index.html predeterminada que acabamos de crear.
A continuación, cree un nuevo archivo PHP 'info.php' en el directorio '/webroot' para asegurarse de que el servicio PHP-FPM se esté ejecutando.
Crea el archivo 'info.php' usando el siguiente comando.
echo '<?php phpinfo(); ?>' > /webroot/info.php
A continuación, abra su navegador web y escriba la dirección IP de su servidor con el puerto '8080' siguiendo la ruta del archivo 'info.php'.
http://ip-del-servidor:8080/info.php
Ahora obtendrá la página phpinfo como se muestra a continuación.
Como se puede ver, el 'contenedor de prueba' se cargó con éxito el script PHP.
Y como resultado, creamos con éxito una nueva imagen de Docker personalizada y ejecutamos el nuevo contenedor basado en ella con cualquier error.