Docker II – Construyendo un contenedor

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:

Docker hello world web
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.

 

Otros enlaces relacionados:

Desplegando un registro de Docker privado y seguro

Docker – Entregando Software

Deja un comentario

¿Necesitas una estimación?

Calcula ahora