Siguiendo con los tutoriales de Docker, en este post vamos a ver las diferentes formas de crear imágenes propias en Docker y cómo subir una image a nuestra cuenta de Docker Registry para poder utilizarla en repetidas ocasiones.

Antes que nada, comentaré algo las imágenes de Docker y la información que tenemos de ellas.


Comprendiendo las imágenes

Las images son la base de los contenedores. Para listar las imágenes que tenemos en nuestro host, ejecutamos:

$ > sudo docker images

REPOSITORY         TAG       IMAGE ID       CREATED      VIRTUAL SIZE
phusion/baseimage  0.9.15    cf39b476aeec   10 weeks ago     289 MB
training/webapp    latest    31fa814ba25a   6 months ago     278.6 MB
ubuntu             14.04     74fe38d11401   4 months ago     180 MB
ubuntu             12.04     5e019ab7bf6d   10 months ago    209.6 MB

En ella podemos ver:

  • El repositorio del que provienen la imagen. Normalmente (aunque no en todos los casos) el nombre del repositorio está compuesto por 2 partes: el usuario (normalmente el tuyo en Docker Hub) y el nombre descriptivo de la imagen.

  • El tag/versión de la imagen

  • El id de la imagen

Un mismo repositorio puede contener diferentes versiones de una imagen. En el siguiente ejemplo, del respoitorio ubuntu nos hemos descargado las imágenes de etiquetadas como 14.04 y 12.04 y ejecutamos una sesión de terminal.

$ > sudo docker run -i -t ubuntu:14.04 /bin/bash

Si sólo queremos descargarnos una imagen, lo hacemos de la siguiente forma:

$ > sudo docker pull ubuntu:14.04

NOTA: Si no especificamos el tag, por defecto nos descarga la imagen etiquetada como latest.


Creando nuestras propias imágenes

Esta es la forma fácil de descargarse una imagen. Pero, ¿y si queremos crearnos nuestra propia imagen? Tenemos 2 formas de hacerlo:

  1. Crear un container a partir de una imagen, modificarlo (instalando el software que queramos) y aplicamos los cambios para crear una nueva imagen

  2. Crear una imagen desde cero utilizando un fichero Dockerfile para especificar las dependencias de la imagen a construir.


Modificar un contenedor y guardarlo como un imagen

El primer método consiste en crear una imagen modificando un contenedor. Por ejemplo, creamos un contenedor basado en la imagen del repositorio training/sinatra:

$ > sudo docker run -t -i training/sinatra /bin/bash

A continuación modificamos dicho contenedor, por ejemplo, instalando git:

root@c1bf43cf22d2:/# apt-get install git

Aplicamos los cambios y creamos la nueva imagen:

$ > sudo docker commit -m="Instalando GIT" -a="Koldo HM" c1bf43cf22d2 koldo/sinatra-dev:v0.1

, donde:

  • -m es el mensaje del commit

  • -a indica el autor

  • c1bf43cf22d2 es el id del contentenedor del que queremos crear una imagen

  • koldo/sinatra-dev:v0.1 es el nombre de la nueva imagen y el valor del tag

Desde este momento, ya tenemos la imagen disponible para poder utilizarla:

$ > sudo docker images

REPOSITORY         TAG    IMAGE ID      CREATED          VIRTUAL SIZE
koldo/sinatra-dev  v0.1   293cbbec56a3  8 seconds ago    446.9 MB

$ > sudo docker run -t -i koldo/sinatra-dev:v0.1 /bin/bash

Esta es la forma más sencilla de crear una imagen pero es poco operativa si tenemos que compartirla y distribuirla entre nuestro equipo de desarrollo.


Construir una imagen en base a Dockerfile

La otra forma de construir una imagen es a través de un fichero llamado Dockerfile donde especificamos las dependencias o características que debe tener nuestra imagen. Es decir, Docker es capaz de construir una imagen a partir de las instrucciones y características definidas en el ficher Dockerfile.

Para ello, seguimos los siguientes pasos:

  • Creamos en nuestro host la carpeta donde vamos a guardar la imagen

    $ > mkdir my-virtual-machines
    $ > cd my-virtual-machines
    
  • Creamos el fichero Dockerfile

    $ > sudo vim Dockerfile
    
  • Configuramos el Dockerfile

    # Este es mi primer dockerfile
    FROM ubuntu:14.04
    MAINTAINER Koldo Hernández <info@koldohernandez.com>
    RUN apt-get update && apt-get install -y git
    RUN sudo mkdir carpeta_prueba
    
  • Construimos la imagen con el comando docker build

    $ > sudo docker build -t koldo/ubuntu-git:v0.1 .
    

    , donde -t nos permite asociar el nombre del repositorio y el tag (esto opcional) y el . del final indica el path donde esta el fichero Dockerfile (podría ser cualquier ruta).

Tras pasarse un rato descargando librerías, etc… finalmente podemos ver como nuestra imagen ha sido creada ejecutando:

$ > sudo docker images

REPOSITORY        TAG       IMAGE ID      CREATED      VIRTUAL SIZE
koldo/ubuntu-git  v0.1    20bfedd3bc81    10 minutes ago   250.6 MB

Podemos ejecutar un contenedor basado en dicha imagen con el siguiente comando:

$ > sudo docker run -i -t koldo/ubuntu-git:v0.1 /bin/bash

, y ver que tenemos la carpeta de prueba carpeta_prueba creada y git instalado:

root@fac79f0bcc78:/# ls -ll
total 68
drwxr-xr-x  2 root root 4096 Dec 10 00:15 bin
drwxr-xr-x  2 root root 4096 Apr 10  2014 boot
drwxr-xr-x  2 root root 4096 Dec 17 23:57 carpeta_prueba
…   
root@fac79f0bcc78:/# git --version
git version 1.9.1

En otro post repasaremos las instrucciones y comandos de un Dockerfile y entraremos un poco más en detalle sobre los mismos.

NOTA IMPORTANTE: es recomendable que lo hagas de esta forma, creando un directorio vacio, y dentro de él crear el fichero Dockerfile. Ejecutando docker build estando en ese directorio. Esto es así porque el comando utiliza el directorio que contiene el Dockerfile como contexto para la construcción de la imagen (incluyendo todos sus subdirectorios).


Subir nuestra imagen a Docker Hub

Una vez tengamos nuestra imagen creada, podemos subirla a un repositorio de Docker Hub. Lo primero que tienes que hacer es crearte una cuenta en Docker Hub.

Una vez hecho, para subir la nueva imagen creada a partir del Dockerfile ejecutamos el siguiente comando:

$ > sudo docker push koldo/ubuntu-git

The push refers to a repository [koldo/ubuntu-git] (len: 1)
Sending image list
2014/12/18 09:03:17 Error: Status 403 trying to push repository koldo/ubuntu-git: "Access Denied: Not allowed to create Repo at given location"

Como vemos, nos va a dar un error. Esto es porque sólo se puede subir esa imagen al repositorio si eres el propietario de koldo/ubuntu-git. Este es un error muy común y la solución es realmente sencilla.

Lo que debemos hacer es modificar el nombre del repositorio con nuestro nombre de usuario del Docker Hub. Para ello ejecutamos:

$ > sudo docker tag koldo/ubuntu-git:v0.1 khernandez/ubuntu-git:v0.1

, donde khernandez es mi nombre de usuario en Docker Hub (debes sustituirlo por el tuyo). Ahora no deberíamos tener problemas a la hora de subir la imagen al repositorio:

$ > sudo docker push khernandez/ubuntu-git

Es probable que cuando ejecutes docker images veas tanto la imagen tageada incorrectamente como la nueva que has subido al respositorio. Es recomendable que elimines la imagen incorrecta para evitar futuros errores:

$ > sudo docker rmi -f koldo/ubuntu-git:v0.1

Untagged: koldo/ubuntu-git:v0.1



En próximos artículos iré profundizando en otras características de Docker.