Variádico

Dockarizar Postgres y retener datos

25 de mayo de 2015

Como todos saben ya, Docker, y contenedores de aplis en general, es el futuro de desarrollo de aplicaciones. Ya existe mucha información básica, pero si apenas te estas enterando de Docker, entonces te recomiendo tomar una gira por Docker aquí. En este tutorial, voy a explicar cómo crear una instancia de Postgres y también cómo retener tus datos tras ejecutar varios contenedores.

Obtener imagen oficial de Postgres

La imagen oficial de Postgres está en Docker Hub. Puedes bajarla usando este comando.

$ docker pull postgres

Si descargaste la imagen en el pasado, entonces docker va a usar la copia local. Para ver cuales imágenes tienes en tu sistema, puedes usar el subcomando images así.

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
postgres            latest              b733b00eb1ae        9 days ago          213.9 MB

Ejecutar contenedor Postgres

Ahora que tenemos la imagen del contenedor de Postgres, podemos iniciar el contenedor usando esta orden.

$ docker run --rm -p 5432:5432 -e POSTGRES_PASSWORD=micontra postgres

Esto es lo que quiere decir todo eso.

Crear, insertar, y consular al banco de datos

Era fácil crear un programa corto para insertar y consultar el bando de datos. Aquí te dejo un ejemplo.

// prueba.go

package main

import (
	"database/sql"
	"fmt"
	"log"

	_ "github.com/lib/pq"
)

func main() {
	db, err := sql.Open("postgres", "user=postgres password=micontra dbname=postgres host=192.168.59.103 sslmode=disable")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	_, err = db.Exec("create table misdatos(id serial primary key, val integer not null)")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("pude crear una tabla")

	for i := 0; i < 10; i++ {
		_, err = db.Exec("insert into misdatos(val) values(1)")
		if err != nil {
			log.Fatal(err)
		}
	}
	fmt.Println("pude insertar datos")

	rows, err := db.Query("select id from misdatos")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	for rows.Next() {
		var id int

		if err = rows.Scan(&id); err != nil {
			log.Fatal(err)
		}

		fmt.Println("id:", id)
	}

	fmt.Println("todo bien")
}

¡IMPORTANTE! Si vas a usar este código, tendrás que cambiar host=192.168.59.103 ¡a la dirección correcta para tu entorno. En OS X, puedes ver la dirección ¡correcta si das echo $DOCKER_HOST.

Si no hay errores con el programa, entonces quiere decir que pudiste crear una tabla, insertar datos, y consultar el banco de datos. Genial. Todo bien. Ahora vamos a detener el contenedor y reiniciarlo. Primero tenemos que obtener el nombre del contenedor con el comando docker ps y luego damos la orden para detener ese contenedor. Usa el mismo comando de antes para iniciar el contenedor de nuevo.

$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                    NAMES
c11194857b9b        postgres:latest     "/docker-entrypoint.   28 minutes ago      Up 28 minutes       0.0.0.0:5432->5432/tcp   distracted_carson

$ docker stop distracted_carson
distracted_carson

$ docker run --rm -p 5432:5432 -e POSTGRES_PASSWORD=micontra postgres

Ahora, otra vez, ejecuta tu programa para insertar al banco de datos. ¿Había errores? Si no, entonces se nos borró todos los datos.

Crear un contenedor de datos

Para retener la información del banco de datos tenemos que crear un contenedor de datos y enlazarlo al contenedor de Postgres. Esto es fácil.

$ docker create -v /var/lib/postgresql/data --name datospg postgres /bin/true

Ahí les va la explicación.

Enlazar contenedor de datos al contenedor Postgres

Puedes enlazar los dos contenedores con este comando.

$ docker run --rm --volumes-from datospg -p 5432:5432 --name pg1 postgres

Comprobar de nuevo

Otra vez, intenta crear una tabla, insertar datos, y consular el banco. Y detiene el contenedor de nuevo. Al reiniciar el contenedor, con la opción --volumes-from datospg, claro, vas a ver que sí se retuvieron todos tus datos.

Muy largo; no leí

En resumen, así puedes crear un contenedor de datos y enlazarlo a Postgres para retener datos.

$ docker pull postgres
latest: Pulling from postgres
...
Status: Downloaded newer image for postgres:latest
$ docker create -v /var/lib/postgresql/data --name datospg postgres /bin/true
76042a48c6b272b9f744f769003684e3898bfe7b80a6b0bba450e4407f816acb
$ docker run --volumes-from datospg -p 5432:5432 --name pg1 -d postgres
38239b1402d90702b01e4cafb57cb45a9bcce5ee410efb42407208a499b2741b