tutorial - ¿Cómo ejecutar un servidor Redis Y otra aplicación dentro de Docker?
docker compose tutorial español (3)
Creé una aplicación Django que se ejecuta dentro de un contenedor Docker. Necesitaba crear un hilo dentro de la aplicación Django, así que usé Apio y Redis como Base de datos de apio. Si instalo redis en la imagen del acoplador (Ubuntu 14.04):
RUN apt-get update && apt-get -y install redis-server
RUN pip install redis
El servidor Redis no se inicia: la aplicación Django arroja una excepción porque la conexión se rechaza en el puerto 6379. Si inicio manualmente Redis, funciona.
Si inicio el servidor Redis con el siguiente comando, se bloquea:
RUN redis-server
Si trato de modificar la línea anterior, tampoco funciona:
RUN nohup redis-server &
Entonces mi pregunta es: ¿hay alguna manera de iniciar Redis en segundo plano y hacer que se reinicie cuando se reinicie el contenedor Docker?
El "último comando" de Docker ya se usa con:
CMD uwsgi --http 0.0.0.0:8000 --module mymodule.wsgi
use supervisord que controlaría ambos procesos. El archivo conf podría verse así:
...
[program:redis]
command= /usr/bin/redis-server /srv/redis/redis.conf
stdout_logfile=/var/log/supervisor/redis-server.log
stderr_logfile=/var/log/supervisor/redis-server_err.log
autorestart=true
[program:nginx]
command=/usr/sbin/nginx
stdout_events_enabled=true
stderr_events_enabled=true
RUN
comandos RUN
agregan nuevas capas de imagen. No se ejecutan durante el tiempo de ejecución. Solo durante el tiempo de compilación de la imagen.
Use CMD
lugar. Puede combinar varios comandos al externalizarlos en un script de shell invocado por CMD
:
CMD start.sh
En el script start.sh
, escribe lo siguiente:
#!/bin/bash
nohup redis-server &
uwsgi --http 0.0.0.0:8000 --module mymodule.wsgi
Cuando ejecuta un contenedor Docker, siempre hay un único proceso de nivel superior. Cuando enciendes tu computadora portátil, ese proceso de nivel superior es un script "init", systemd o similar. Una imagen de acoplador tiene una directiva ENTRYPOINT. Este es el proceso de nivel superior que se ejecuta en el contenedor de la ventana acoplable, y cualquier otra cosa que desee ejecutar es hija de eso. Para ejecutar Django, un Apio Worker y Redis dentro de un solo contenedor Docker, debería ejecutar un proceso que los inicie a los tres como procesos secundarios. Como explicó Milan, podría configurar una configuración de Supervisor para hacerlo e iniciar el supervisor como su proceso principal.
Otra opción es realmente arrancar el sistema init. Esto te acercará mucho a lo que deseas, ya que básicamente funcionará como si tuvieras una máquina virtual a escala completa. Sin embargo, pierdes muchos de los beneficios de contenerización al hacer eso :)
La forma más simple es ejecutar varios contenedores utilizando Docker-compose. Un contenedor para Django, uno para su trabajador de Apio y otro para Redis (¿y uno para su tienda de datos también?) Es bastante fácil de configurar de esa manera. Por ejemplo...
# docker-compose.yml
web:
image: myapp
command: uwsgi --http 0.0.0.0:8000 --module mymodule.wsgi
links:
- redis
- mysql
celeryd:
image: myapp
command: celery worker -A myapp.celery
links:
- redis
- mysql
redis:
image: redis
mysql:
image: mysql
Esto le daría cuatro contenedores para sus cuatro procesos de nivel superior. redis y mysql estarían expuestos con el nombre dns "redis" y "mysql" dentro de los contenedores de su aplicación, por lo que en lugar de apuntar a "localhost" apuntaría a "redis".
Hay mucha información buena en Dock-compose docs