Uno de los casos de uso más simples para poder utilizar
Docker, es creando una web local en un entorno de desarrollo. Como el entorno
nos permite replicarlo al entorno de producción, nos aseguramos que nuestros
desarrollos siempre se ejecutarán en producción. Vamos a realizar una prueba
instalando un servidor web Nginx en un contenedor para ejecutar una página web
sencilla. Nuestro sitio web se va a llamar ejemplo.
Para conseguirlo, vamos a comenzar con un simple Dockerfile.
Comenzamos creando un directorio donde crear nuestro fichero Dockerfile.
mkdir ejemplo
cd ejemplo
touch Dockerfile
Ahora necesitamos algunos ficheros de configuración de Nginx
para nuestro sitio web. Vamos a crear un directorio llamado nginx dentro de
nuestro directorio ejemplo.
y dentro del mismo creamos un fichero de configuración
global.conf con el siguiente contenido:
server
{
listen 0.0.0.0:80;
server_name _;
root /var/www/html/website;
index index.html index.htm;
access_log /var/log/nginx/default_access.log;
error_log /var/log/nginx/default_error.log;
}
y otro fichero denominado nginx.conf
user
www-data;
worker_processes
4;
pid
/run/nginx.pid;
daemon
off;
events
{ }
http
{
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
include /etc/nginx/conf.d/*.conf;
}
y ahora vamos a crear nuestro fichero Dockerfile
FROM ubuntu:14.04
MAINTAINER Javier Hernandez
ENV ACTUALIZADO_FECHA 29-12-2015
RUN
apt-get –yqq update && apt-get –yqq install nginx
RUN
mkdir –p /var/www/html/web
ADD
nginx/global.conf /etc/nginx/conf.d/
ADD
nginx/nginx.con /etc/nginx/nginx.conf
EXPOSE 80
Nuestro fichero Dockerfile realiza lo siguiente:
·
Instala Nginx
·
Crea un directorio /var/www/html/web/ dentro de
la imagen.
·
Añade la configuración de nginx desde nuestro
sistema de ficheros local a nuestra imagen
·
Publica el puerto 80 en la imagen
Nuestros dos ficheros de configuración de Nginx son
copiados. Global.conf es copiado a la carpeta /etc/nginx/conf.d mediante la
instrucción ADD y el fichero nginx.conf es copiado al directorio /etc/nginx
En este fichero de configuración, la opción “daemon off” fuerza
que nginx no se ejecute como demonio o servicio, esto es, porque nuestro
contenedor Docker se encargará de que el proceso se mantenga activo por
defecto, esto hará que se ejecute como demonio cuando el contenedor comience y
se parará cuando el mismo se pare.
Podemos ver también algunas diferencias entre las rutas
destino de las dos instrucciones ADD, la primera termina en un directorio, pues
acaba con “/” y la segunda especifica un fichero, los dos estilos están
permitidos para copiar ficheros en una imagen Docker.
Ahora vamos a crear nuestra nueva imagen con el comando
Docker build, la vamos a llamar “jalapuente/nginx”.
docker
build –t jalapuente/nginx .
Esto construirá y nombrará nuestra nueva imagen y veremos
como se van ejecutando los distintos pasos. Podemos ver las capas y pasos
utilizados utilizando el comando “docker
history”.
$
docker history jalapuente/nginx
IMAGE CREATED CREATED BY SIZE COMMENT
22aa8432c73e 22 hours ago /bin/sh -c #(nop) EXPOSE 80/tcp 0 B
da09a1e3cde1 22 hours ago /bin/sh -c #(nop) ADD
file:6b400357b23615a407 415 B
9f9c6ca0ee34 22 hours ago /bin/sh -c #(nop) ADD
file:527ff78465dc48bf6c 286 B
3082b1b65403 22 hours ago /bin/sh -c mkdir /var/web 0 B
d93ddca5468f 23 hours ago /bin/sh -c apt-get update &&
apt-get install 39.58 MB
61da7c1ebfde 23 hours ago /bin/sh -c #(nop) ENV
ACTUALIZADO_FECHA=29-12 0 B
a7518518555c 23 hours ago /bin/sh -c #(nop) MAINTAINER Javier
Hernandez 0 B
89d5d8e8bafb 3 weeks ago /bin/sh -c #(nop) CMD
["/bin/bash"] 0
B
e24428725dd6 3 weeks ago /bin/sh -c sed -i
's/^#\s*\(deb.*universe\)$/ 1.895
kB
1796d1c62d0c 3 weeks ago /bin/sh -c echo '#!/bin/sh' >
/usr/sbin/polic 194.5 kB
0bf056161913 3 weeks ago /bin/sh -c #(nop) ADD
file:9b5ba3935021955492 187.7 MB
El comando nos muestra al principio la capa final, nuestra
nueva imagen tiene como padre original a ubuntu:14.04. Cada paso nos muestra
una nueva capa y la instrucción del fichero Dockerfile que la ha generado.
Creando contenedores
de nuestra imagen nginx en nuestro sitio web de ejemplo
Ahora tenemos nuestra imagen jalapuente/nginx y podemos empezar
a crear contenedores de ella, lo que permitirá poner a prueba nuestra página
web de ejemplo. Para ello, tenemos que añadir el código de la página web de ejemplo.
$
mkdir web && cd web
$
nano index.html
<head>
<title>Sitio web de ejemplo
</title>
</head>
<body>
<h1>Esto
es una prueba de sitio web</h1>
</body>
Esto creará un directorio llamado web. Luego creamos archivo
index.html para nuestro sitio web de ejemplo.
Ahora vamos a ver cómo podemos ejecutar un contenedor
utilizando el comando docker run.
$ docker
run -d -p 80 --name web -v $PWD/web:/var/web jalapuente/nginx nginx
Podemos ver que hemos pasado el comando nginx como parámetro
al comando docker run. Normalmente esto no tendría que ser necesario para
ejecutar Nginx. En la configuración suministrada a Docker, hemos añadido la
directiva daemon off. Esta directiva hace que Nginx se ejecute de forma
interactiva cuando es ejecutado.
Se puede ver que hemos utilizado el comando docker run para
crear un contenedor desde nuestra imagen jalapuente/nginx llamada web. Aquí podemos ver que hemos
utilizado la opción -v. Esta nueva opción nos permite crear un volumen en
nuestro contenedor de un directorio en el host.
Vamos a ver los volúmenes, ya que son importantes y útiles
en Docker. Los volúmenes están especialmente designando directorios dentro de
uno o más contenedores que no utilizan el sistema de archivos en capas para
proporcionar datos persistentes o compartidos por Docker. Esto significa que
los cambios en un volumen se hacen directamente y no tienen nada que ver con la
imagen. Los volúmenes no se incluirán cuando construimos una imagen.
Los volúmenes también pueden ser compartidos ente
contenedores y pueden persistir incluso cuando se detienen los contenedores.
Aquí podemos ver algunos casos que pueden resultar útiles,
podemos ver el valor de volúmenes cuando no queremos para construir nuestra
aplicación o código en una imagen. Por ejemplo:
• Queremos trabajar y probarlo de forma simultánea.
• La información cambia con frecuencia, y no queremos
reconstruir la imagen durante nuestro proceso de desarrollo.
• Queremos compartir el código fuente entre varios
contenedores.
La opción -v funciona mediante la especificación de un
directorio del host local separado por dos puntos del directorio a montar dentro
del contenedor. Si el directorio contenedor no existe, Docker lo creará.
También podemos especificar el modo en que se monta el
volumen, bien de lectura/escritura del directorio contenedor añadiendo rw o bien
de sólo lectura añadiendo ro después del directorio, por ejemplo:
$ docker
run -d -p 80 --name web -v $PWD/website:/var/www/html/website: ro jalapuente/nginx
nginx
Esto haría que el contenedor montara el directorio /var/www/html/website
de sólo lectura.
En nuestro sitio web que utiliza el contenedor Nginx, para
ello, hemos montado un sitio Web local que estamos desarrollando. Para ello
hemos montado como volumen el directorio $PWD/website como directorio
/var/www/html/website en nuestro contenedor. En nuestra configuración de Nginx
(en el archivo de configuración /etc/nginx/conf.d/global.conf), hemos
especificado este directorio como la ubicación para ser servido por el servidor
Nginx.
Ahora bien, si nos fijamos en nuestro contenedor en
ejecución con el comando docker ps, podemos ver que está activo, se nombra web,
y el puerto 80 en el contenedor se asigna al puerto 32768 en el host.
$
docker ps -l
CONTAINER
ID IMAGE COMMAND CREATED STATUS PORTS NAMES
783b2527f17f jalapuente/nginx "nginx" 6 seconds ago Up 6 seconds 0.0.0.0:32768->80/tcp web
Si navegamos al puerto 32768 en nuestro anfitrión Docker,
vamos a ser capaces de ver nuestra página web de muestra, en este caso he
creado un fichero index.html con el texto “prueba”.
Fuente: Elaboración
propia
En nuestro caso, hemos realizado el ejemplo utilizando
“Docker Toolbox” el cual utiliza docker-machine, hemos tenido que ver que
dirección IP tenía nuestro demonio docker para poder mostrar nuestro sitio web,
en mi caso, la máquina docker dentro de docker-machine se llama docker2, así
que ejecutamos lo siguiente para averiguar su IP:
$ docker-machine ip docker2
192.168.99.100
Ahora vamos a editar nuestro sitio web:
$ nano $PWD/website/index.html
y ponemos:
Esto es una prueba de sitio web con Docker
Entonces pulsamos la tecla refrescar de nuestro navegador y
vemos el resultado:
Fuente: Elaboración
propia
Podemos ver que nuestro sitio web de ejemplo ha sido
actualizado. Esto es un ejemplo increíble y bastante simple de editar un sitio
web, pero podríamos hacer muchísimo más, cosas más importantes, incluso sitios
que reflejen la información de producción realmente. Podemos tener contenedores
para cada tipo de entorno de producción como Apache, nginx, etc…, para poder
ejecutar variedad de versiones de framework como PHP o conectar a unas u otras
bases de datos.