miércoles, 20 de julio de 2016

Creando un sitio web estático con Docker


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.

mkdir nginx && cd nginx

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.

No hay comentarios:

Publicar un comentario