En nuestro último artículo presentamos un resumen de qué es Docker y cómo puede ayudarnos en el desarrollo de software.
Esta semana os enseñaremos a crear un contenedor en el que correrá un servidor web que aloja una simple página web estática.
Hay varias maneras de trabajar con Docker. Asumimos que ya tienes un entorno configurado (https://docs.docker.com/installation/#installation).
En Solid Gear, normalmente utilizamos servidores Ubuntu y configuramos nuestros Docker host usando los paquetes actualizados de Docker (https://docs.docker.com/installation/ubuntulinux/). Para continuar con el resto de esta guía, debes ser capaz de ejecutar el comando “docker ps” sin errores:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Hello World
Para ir calentando, vamos a arrancar un contenedor predefinido registrado en el Docker Hub y hacer que ese contenedor imprima «Hello World».
Usando el comando «docker run» podemos arrancar un contenedor que esté definido en una imagen local o remota en un registro (un repositorio centralizado).
$ docker run ubuntu:14.04 /bin/echo 'Hello world' Unable to find image 'ubuntu:14.04' locally 14.04: Pulling from ubuntu e9e06b06e14c: Pull complete a82efea989f9: Pull complete 37bea4ee0c81: Pull complete 07f8e8c5e660: Already exists ubuntu:14.04: The image you are pulling has been verified. Important: image verification is a tech preview feature and should not be relied on to provide security. Digest: sha256:125f9479befe1f71562b6ff20fb301523a2633902ded6d50ade4ebcd7637a035 Status: Downloaded newer image for ubuntu:14.04 Hello world
¿Qué hace este comando?
Si todavía no tenemos la imagen ubuntu:14.04 descargada, Docker la cogerá del registro y la reconstruirá capa por capa(hablaremos de las capas más adelante).
Es importante resaltar que podemos especificar una versión diferente de Ubuntu por medio de tags (por ejemplo, podríamos haber elegido ubuntu:15.04).
Una vez descargada, arrancamos el contenedor usando el comando “run” y ejecutamos “echo Hello World”.
Si volvemos a ejecutar este comando no tendremos que volver a descargar la imagen, ya que disponemos de una copia local:
$ docker run ubuntu:14.04 /bin/echo 'Hello world' Hello world
Definiendo un contenedor
Los contenedores de Docker se definen usando un fichero Dockerfile. Este fichero especifica el contenedor base a partir del cual construiremos nuestra aplicación. Por ejemplo, para nuestro contenedor empezaremos con la siguiente definición de contenedor:
FROM ubuntu:14.04 MAINTAINER Grant Croker <gcroker+docker@solidgear.es> RUN apt-get update && apt-get install apache2
Esto especifica la imagen base que queremos usar para el contenedor, en este caso, Ubuntu 14.04, el encargado de mantenerla y el software que queremos instalar. Para construir este contenedor tendrás que guardar las líneas anteriores en el fichero Dockerfile y usar el comando “docker build”, como por ejemplo:
$ docker build -t gcroker/docker-demo .
Ya podemos arrancar el contenedor (usando “docker run”), pero de momento no hace gran cosa:
$ docker run -d -p 80:80 gcroker/docker-demo
Para confirmar esto, utilizaremos el comando «docker ps» para listar los contenedores actuales y antiguos (-a).
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ba7a22ac0419 gcroker/docker-demo:latest "/bin/bash" 4 seconds ago Exited (0) 1 seconds ago kickass_swartz
Ahora necesitamos añadir nuestra página web y un script que arranque apache. Primero creamos un fichero llamado hello_world.htm en la carpeta donde tenemos nuestro Dockerfile con el siguiente contenido:
<html>
<head>
<title>Docker - Hello World</title>
</head>
<body>
<p>
Hello World!!
</p>
</body>
</html>
Además, tenemos que añadir las siguientes líneas a nuestro Dockerfile:
COPY hello_world.html /var/www/html/ CMD ["/usr/sbin/apache2ctl", "-e", "info", "-DFOREGROUND"]
La primera línea copiará en el contenedor la página web que acabamos de crear. Luego, usamos el CMD para que el contenedor ejecute Apache en primer plano lanzando los logs de errores en la consola.
Ahora tenemos que volver a crear imagen con las nuevas líneas. Te darás cuenta que «docker build» no crea la imagen desde cero, sino que ésta se construye, «por encima» de las definiciones previas:
$ docker build -t gcroker/docker-demo . Step 0 : FROM ubuntu:14.04 ---> 07f8e8c5e660 Step 1 : MAINTAINER Grant Croker <gcroker+docker@solidgear.es> ---> Using cache ---> f12ac6b46f7b Step 2 : RUN apt-get update && apt-get install -y apache2 ---> Using cache ---> 8dd3d98002ab Step 3 : COPY hello_world.html /var/www/html/ ---> 85be7f25b089 Removing intermediate container 79248e637bf1 Step 4 : CMD /usr/sbin/apache2ctl -e info -DFOREGROUND ---> Running in 2ac337e8aa74 ---> 9738a8c77aee Removing intermediate container 2ac337e8aa74 Successfully built 9738a8c77aee
Deberíamos ser capaces de arrancar el contenedor y conectarnos a él:
$ docker run -d -p 80:80 gcroker/docker-demo
Con este comando conseguimos que el contendor se ejecute en segundo plano (-d), mapeando el puerto 80 del contendor con el puerto 80 donde está Apache está escuchando (-p 80:80).
Para confirmar que el contenedor está corriendo, usamos “docker ps”:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f95e0da2d3ee gcroker/docker-demo:latest "/usr/sbin/apache2ct 7 minutes ago Up 7 minutes 0.0.0.0:80->80/tcp furious_einstein
Y podemos ver los logs con “docker logs”:
$ docker logs f95e0da2d3ee AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.20. Set the 'ServerName' directive globally to suppress this message.
El último test será conectarse al servidor con un navegador, usando la IP (o nombre) del «docker host», para confirmar que tenemos acceso a la página web que hemos creado:
La próxima vez examinaremos aplicaciones más complejas que usen varios contenedores y veremos cómo se conectan entre ellos.
Los ficheros que hemos usado para este post se pueden descargar desde el repositorio docker-demo en Github.