如何在Docker中运行Redis服务器和另一个应用程序?

我创build了一个在Docker容器中运行的Django应用程序。 我需要在Django应用程序中创build一个线程,所以我使用Celery和Redis作为Celery数据库。 如果我在docker映像(Ubuntu 14.04)中安装redis:

RUN apt-get update && apt-get -y install redis-server RUN pip install redis 

Redis服务器没有启动:Django应用程序抛出一个exception,因为端口6379上的连接被拒绝。如果我手动启动Redis,它将起作用。

如果使用以下命令启动Redis服务器,则会挂起:

 RUN redis-server 

如果我尝试调整前一行,它也不起作用:

 RUN nohup redis-server & 

所以我的问题是:是否有办法在后台启动Redis,并重新启动Docker容器时重新启动?

Docker“last command”已经用于:

 CMD uwsgi --http 0.0.0.0:8000 --module mymodule.wsgi 

RUN命令仅添加新的图像层。 它们不会在运行时执行。 只在图像的build立时间。

改用CMD 。 您可以通过将多个命令外化为一个由CMD调用的shell脚本来组合多个命令:

 CMD start.sh 

start.sh脚本中,您可以编写以下内容:

 #!/bin/bash nohup redis-server & uwsgi --http 0.0.0.0:8000 --module mymodule.wsgi 

使用supervisord来控制这两个进程。 conf文件可能如下所示:

 ... [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 

在运行Docker容器时,总是有一个顶级进程。 当您启动笔记本电脑时,该顶层进程是一个“init”脚本,systemd或类似的东西。 泊坞窗图像有一个ENTRYPOINT指令。 这是在Docker容器中运行的顶级进程,其他任何想运行的都是其subprocess。 为了在一个Docker容器中运行Django,Celery Worker和Redis,你将不得不运行一个启动它们全部三个作为subprocess的进程。 正如米兰所解释的那样,您可以设置一个主pipeconfiguration来执行此操作,并启动主pipe作为您的父级进程。

另一种select是实际启动init系统。 这会让你非常接近你想要的东西,因为它基本上就像拥有一个全面的虚拟机一样运行。 但是,通过这样做你会失去集装箱化的许多好处:)

最简单的方法就是使用Docker-compose来运行多个容器。 Django的一个容器,一个用于你的Celery工作者,另一个用于Redis(还有一个用于你的数据存储的容器),这个容器很容易设置。 例如…

 # 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 

这将为您提供四个顶级过程的容器。 redis和mysql会暴露在您的应用程序容器中的dns名称“redis”和“mysql”,所以不要指向“localhost”,而是指向“redis”。

Docker-compose文档中有很多很好的信息