Ver contenido
carlosazaustre.es carlosazaustre.es

Desplegando contenedores en DigitalOcean con Docker, Docker Compose y Docker Machine

🗓 | 💻 Desarrollo | 🕐 4 minutos de lectura | 💬 Comments

Hace unos meses escribí un post sobre como manejar contenedores Docker en MAC, ya que se necesita una máquina virtual (boot2docker) para poder utilizarlos.

Hoy quería probar Docker en producción y en este artículo voy a subir el API REST que hice anteriormente con Node/Io.js y MongoDB pero en dos contenedores Docker diferentes (uno con la aplicación Node/IO y otro con MongoDB) a un instancia de DigitalOcean desde contenedores Docker. Vamos allá.

El código fuente de este proyecto lo tienes en GitHub como siempre. Siéntete libre de descargarlo y usarlo.

  1. Montando el entorno con Docker Compose
  2. Desplegando los contenedores con Docker Machine

Si tienes dudas sobre Docker, te recomiendo que leas el artículo que escribí hace un tiempo sobre ello.


Montando el entorno con Docker Compose

Primero necesitamos montar el entorno de trabajo en local. Como dije en la introducción vamos a usar dos contenedores, uno para servicio, el API REST en Node u IO.js será uno, y el otro será el que contenga la base de datos, en este caso MongoDB. SI por ejemplo usásemos Nginx, Redis, etc... irían en otros contenedores diferentes. De esta forma, si necesitamos escalar, podemos poner cada contenedor en una máquina más adelante sin mucha dificultad.

docker containers mongodb node

Una vez tenemos instalado Docker en nuestros equipos, levantamos el servicio, en el caso de Mac, usando boot2docker y recargando las variables de entorno de Docker que contienen la IP privada, etc...

Para poder manejar varios contenedores de manera sencilla y poder levantarlos y pararlos en conjunto, instalaremos Docker Compose, con el que a a través de un fichero .yml configuraremos nuestro entorno fácilmente.

Ya sea desde Mac o Linux, lo podemos instalar así:

Nota Como vamos a probar varias veces, seguramente querremos borrar y parar los contenedore e imágenes que creamos más de una vez, y hacerlo de uno en uno puede resultar desesperante, por tanto estos dos comandos de a continuación nos harán ahorrar tiempo: Eliminar todos contenedores $ docker rm $(docker kill $(docker ps -aq)) Eliminar todas imágenes $ docker rmi $(docker images -qf "dangling=true") Fuente: Stackoverflow

Creamos un único Dockerfile para nuestra aplicación Node/IO.js, ya que el contenedor de MongoDB lo crearemos desde el propio docker-compose.yml ya que no necesitamos más que la imagen de Mongo. En el caso de la aplicación IO.js, aparte del entorno necesitamos copiar el código del proyecto, instalar dependencias, etc...

Tomamos como imagen fuente la de iojs:2.3.0 creada y mantenida por la propia comunidad de Docker. De esta manera nos ahorramos importar el sistema operativo, configurarlo, instalarle IO.js, Git, etc... , la imagen iojs:2.3.0 ya incorpora todo eso. Si queremos tener un entorno más personalizado podemos hacerlo, pero para este tutorial lo he obviado.

Ya en el fichero docker-compose.yml escribimos todo el entorno para la ejecución de los contenedores

¿Qué estamos indicando en este fichero? Pues, que vamos a crear un contenedor llamado api el cual a través del comando build: . le decimos que lo construya con el Dockerfile que hay en la raiz del proyecto. Cuando finalice su montaje, ejecutará el comando babel-node /iojs-api/index.js --restart=always que es el que lanza el servidor Io.js con nuestro API. Mapeamos el puerto 3000 del contenedor con el 3000 del sistema y con links le decimos que se enlace con el contenedor mongodb que a continuación creamos.

Nota:

Se recomienda no usar supervisores de procesos en contenedores Docker y usar en su lugar el flag --restart=always

Fuente StackOverflow

El contenedor Mongodb no se crea a partir de un Dockerfile por eso no hay comando build pero si un comando image donde le indicamos a partir de que imagen de Docker crearlo, en este caso mongo:2.6. También mapeamos los puertos que vamos a usar, en el caso de Mongo es el 27017

Ejecutando el siguiente comando levantaremos los contenedores y se pondrán en funcionamiento

Si los paramos para hacer cambios y necesitamos reconstruir las imágenes, lo haremos con el comando:

Te habrás fijado que no funciona, y da un error de conexión con Mongo, ¿Sabes por qué? porque la URL de nuestra base de datos Mongo ya no es localhost, es una privada que le asigna Docker. ¿Y cómo lo averiguamos?

Si ejecutas el siguiente comando, podemos ver las variables de entorno que crea Docker para nuestra aplicación

Hay dos que vamos a utilizar MONGODB_1_PORT_27017_TCP_ADDR=172.17.0.4 y MONGODB_1_PORT_27017_TCP_PORT=27017

Son el host y puerto de MongoDB dentro de nuestro contenedor, por tanto vamos a indicárselo en el código, en el fichero index.js cuando nos conectamos a la base de datos.

De esta manera, si las variables de entorno están definidas las usará. Por el contrario si estamos fueras de los contendedor de Docker, empleará localhost

Con los cambios realizados, reconstruimos las imágenes y levantamos de nuevo el entorno:

Si probamos el API en http://dockerhost:3000/employees veremos que funciona:

Screen Shot 2015 06 30 at 10 39 15


Desplegando los contenedores con Docker Machine

Ahora vamos a usar otro proyecto de Docker, llamado Docker Machine que nos permite crear servidores desde la linea de comandos de nuestra terminal y con ayuda de Docker Compose, desplegarlos a producción en segundos

De nuevo vamos a usar DigitalOcean para servir nuestra API contenerizada. Pero podemos usar otros servidores como Amazon, Azure, etc..

Para poder crear servidores con DigitalOcean necesitamos un token que nos dé acceso a su API. Lo podemos conseguir clickando en el menu API dentro de nuestra cuenta.

Screen Shot 2015 06 30 at 10 59 39 Será un número parecido a este: 7ghr3247fg98429jhd5dufhwg325de9ff1ab. Lo copiamos (Ten cuidado de no compartir este número con nadie, o tendrán acceso a tu cuenta)

Ahora desde la linea de comandos, gracias al Access Token de Digital Ocean y su driver podemos crear un droplet con el nombre iojsapi_DO con el comando docker-machine create:

Para poder trabajar con el entorno recién creado, seleccionamos la maquina con el siguiente comando

Si ahora ejecutamos docker-compose se desplegará nuestro entorno en el nuevo droplet creado en DigitalOcean

Podemos ir a un navegador o hacer uso de la aplicación Postman para probar nuestra API que estará corriendo en la IP que DigitalOcean nos ha proporcionado y el puerto 3000. En mi caso en http://45.55.195.22:3000

Screen Shot 2015 06 30 at 11 23 32

¿Notas como tu cerebro ha crecido un poco? :)

Más información:

✎ ¿Ves alguna errata? ¿Quieres modificar algo? Haz una Pull Request.

Carlos Azaustre

Soy Carlos Azaustre. Desarrollador web desde hace más de 8 años. He trabajado en Google, IBM y Eventbrite. Soy GDE (Google Developer Expert) en Tecnologías Web. Desde 2013 intento documentar en éste blog todo lo que aprendo y así compartirlo con el resto de la comunidad.

📬 Únete y ponte al día en desarrollo web

Recibe puntualmente información sobre las últimas novedades en tecnologías web y desarrollo web moderno para que estés siempre actualizadx:

🔒 Libre de Spam. Sólo contenido que te interesa..