Instalando Sentry con docker + systemd

Hace un tiempo había hecho un post de como instalar Sentry en Ubuntu server y lo hacía utilizando VirtualEnv2 y Supervisord.

Ahora mucho tiempo después necesitaba instalar un Sentry y como no me quería complicar ya que este tipo de software suele ser bastante difícil de instalar, decidí buscar la forma de hacerlo con Docker.

En el post "Configurando Dropbox con Docker en Archlinux (+ systemd)" explico como hacer un unit file de systemd para levantarlo como servicio, pero en este caso hay que levantar varios containers, se hace un poco mas complejo.

Primero que nada esto lo hice siguiendo la guía oficial del container mas otras más¹² personalizando un par de cosas.

Primero que nada tenemos que generar un secret code, el container de sentry tiene una opción para esto:

$ docker run --rm sentry config generate-secret-key

Esto de paso nos descargará el container de sentry.

Ahora necesitamos dos cosas:

  • Servidor Redis
  • Servidor Postgres

En la guía oficial los levanta de forma muy simple, pero mi objetivo es que esto quede funcionando en producción, así que primero que nada vamos a crear un directorio donde irán los datos de nuestros containers:

$ mkdir -p /srv/sentry/{redis,postgres,sentry}/data

De ese modo ya podemos crear volúmenes luego.

Levantando Redis

Primero que nada el servidor redis es el mas simple de levantar:

$ docker run -d --name=sentry-redis -v /srv/sentry/redis/redis.conf:/usr/local/etc/redis/redis.conf -v /srv/redis/data:/data  redis redis-server /usr/local/etc/redis/redis.conf

En este caso podemos crear un archivo en /srv/sentry/redis/redis.conf y configurar a gusto nuestro redis.

Levantando Postgres

Ahora necesitamos nuestro postgres, este tiene un par mas de opciones, primero necesitamos definir una contraseña, yo utilicé mi propia herramienta para generar contraseñas llamada genpasswd:

$ genpasswd -al 40
wnDny5y9HnfQL0qG06fPwSEpTQhH9Eh2RZ55wzrq
$ docker run -d --name=sentry-postgres -e POSTGRES_PASSWORD=wnDny5y9HnfQL0qG06fPwSEpTQhH9Eh2RZ55wzrq -e POSTGRES_USER=sentry -e PGDATA=/data -v /srv/sentry/postgres/data:/data  postgres

La primera vez que lo corremos, aparte de descargarlo si no lo tenemos, va a ser crear el árbol de directorio donde guardará las bases de datos, utilizando nuestro volumen en /srv/sentry/postgres/data.

Creamos la base de datos de nuestro Sentry

Ya teniendo levantados ambos servidores, vamos a crear la base de datos, esto lo hacemos con el siguiente comando:

$ docker run -it --rm -e SENTRY_SECRET_KEY='7DzdS*si^b4@v]Pxr%idPx=j"5"wP6' --link sentry-postgres:postgres --link sentry-redis:redis sentry upgrade

Esto puede tardar un rato, y al final nos preguntará si queremos crear un usuario (por eso es importante ejecutarlo en modo interactivo con -it), podemos crear nuestro usuario admin de esa forma siguiendo los pasos, pero si por algún motivo te equivocas, no pasa nada, después podemos crear otros.

Nota: Recordá que 7DzdS*si^b4@v]Pxr%idPx=j"5"wP6 es el valor que nos devolvió el comando generate-secret-key, no uses el mismo que este y genera el tuyo propio!!!

Creamos usuarios

Si querés agregar mas usuarios o te equivocaste en el paso anterior, podemos crear usuarios con:

$ docker run -it --rm -e SENTRY_SECRET_KEY='7DzdS*si^b4@v]Pxr%idPx=j"5"wP6' --link sentry-redis:redis --link sentry-postgres:postgres sentry createuser

Levantamos Sentry

Ahora que ya tenemos todo creado, vamos a levantar nuestro servidor, y ya lo podemos probar, aunque lo primero que nos va a preguntar es la ruta definitiva, con dominio y todo, esto es importante y difícil de modificar después, así que intenta acceder desde dicho dominio.

$ docker run --rm --name=sentry-sentry -e SENTRY_SECRET_KEY='7DzdS*si^b4@v]Pxr%idPx=j"5"wP6' -e  --link sentry-redis:redis --link sentry-postgres:postgres -p 8000:9000  sentry

En este caso, exportamos el puerto 8000 que va a ir al 9000 del container, por lo que podemos comprobarlo entrando a http://ip_o_host:8000.

Nota: Puede que te aparezca un cartel diciendo que no están funcionando los workers de celery, esto es porque tenemos que correr otras dos instancias del container, pero lo veremos después.

Generando el unit file

Bueno lo que vamos a hacer para nuestro unit file, es similar a lo que hice para levantar dropbox en el mencionado anteriormente tutorial, pero vamos a tener que levantar tanto los containers de redis, postgres, y 3 de sentry.

Creamos el archivo /etc/systemd/system/sentry.service con el siguiente contenido:

[Unit]
Description=sentry
After=network.target docker.socket
Requires=docker.socket

[Service]
TimeoutStartSec=0
Restart=always

# Detenemos (si los hay) y eliminamos las insntancias anteriores:

ExecStartPre=-/usr/bin/docker stop sentry-redis
ExecStartPre=-/usr/bin/docker stop sentry-postgres
ExecStartPre=-/usr/bin/docker stop sentry-sentry
ExecStartPre=-/usr/bin/docker stop sentry-cron
ExecStartPre=-/usr/bin/docker stop sentry-worker
ExecStartPre=-/usr/bin/docker rm sentry-redis
ExecStartPre=-/usr/bin/docker rm sentry-postgres
ExecStartPre=-/usr/bin/docker rm sentry-sentry
ExecStartPre=-/usr/bin/docker rm sentry-cron
ExecStartPre=-/usr/bin/docker rm sentry-worker

# Levantamos Redis

ExecStartPre=/usr/bin/docker run -d --name=sentry-redis -v /srv/sentry/redis/redis.conf:/usr/local/etc/redis/redis.conf -v /srv/redis/data:/data  redis redis-server /usr/local/etc/redis/redis.co
nf

# Levantamos postgres

ExecStartPre=/usr/bin/docker run -d --name=sentry-postgres -e POSTGRES_PASSWORD=wnDny5y9HnfQL0qG06fPwSEpTQhH9Eh2RZ55wzrq -e POSTGRES_USER=sentry -e PGDATA=/data -v /srv/sentry/postgres/data:/data  postgres

# Levantamos Sentry

ExecStartPre=/usr/bin/docker run -d --name=sentry-cron -e SENTRY_SECRET_KEY='7DzdS*si^b4@v]Pxr%idPx=j"5"wP6' --link sentry-redis:redis --link sentry-postgres:postgres sentry run cron

ExecStartPre=/usr/bin/docker run -d --name=sentry-worker -e SENTRY_SECRET_KEY='7DzdS*si^b4@v]Pxr%idPx=j"5"wP6' --link sentry-redis:redis --link sentry-postgres:postgres sentry run worker

ExecStart=/usr/bin/docker run --rm --name=sentry-sentry -e SENTRY_SECRET_KEY='7DzdS*si^b4@v]Pxr%idPx=j"5"wP6' --link sentry-redis:redis --link sentry-postgres:postgres -p 8000:9000  sentry

# Despues de detener la instancia de docker, nos aseguramos de detener todas las demas y de borrarlas

ExecStopPost=-/usr/bin/docker stop sentry-redis
ExecStopPost=-/usr/bin/docker stop sentry-sentry
ExecStopPost=-/usr/bin/docker stop sentry-postgres 
ExecStopPost=-/usr/bin/docker stop sentry-cron
ExecStopPost=-/usr/bin/docker stop sentry-worker

ExecStopPost=-/usr/bin/docker rm sentry-redis
ExecStopPost=-/usr/bin/docker rm sentry-postgres 
ExecStopPost=-/usr/bin/docker rm sentry-sentry
ExecStopPost=-/usr/bin/docker rm sentry-cron
ExecStopPost=-/usr/bin/docker rm sentry-worker

[Install]
Also=docker.socket
WantedBy=multi-user.target

Con esto ya podemos levantar todo con systemd, de la siguiente manera:

$ systemctl start sentry

Y si queremos que lo haga en el arranque del sistema:

$ systemctl enable sentry

Si por algún motivo no levanta, se puede ver mas detallado haciendo:

$ journalctl -xefu sentry

Proxiando con Nginx

Esto es simple ya que lo tenemos levantado en el puerto 8000, así que solo tenemos que hacer un proxy reverso a ese puerto.

Te recomiendo seguir mi guía de Configurando un SSL gratis con Let's Encrypt en Nginx ya que de yapa tendrás SSL gratuito.