使用supervisord在Docker容器中管理多个进程

目前工作当中,工具开发主要使用Python的Flask或Django。除了WEB服务本身,可能还会有一些后台定时任务进程需要执行。让自己的多个任务进程在同一个Docker容器中RUN起来,成为一个必须项。

以下我使用supervisord管理容器中的多进程的一些常用配置,供参考。

Alpine版本

FROM harbor.paas.shein.io/helper/compile:latest as builder
ARG REPO
ARG BRANCHNAME
RUN git clone -b $BRANCHNAME $REPO /repo
 
FROM python:3.7-alpine
RUN mkdir -p /opt/repo
COPY --from=builder /repo /opt/repo
WORKDIR /opt/repo
 
RUN apk update -y && \
    apk upgrade && \
    apk add --no-cache build-base bash vim busybox-extras git && \
    apk add --update gcc libc-dev fortify-headers linux-headers && \
    rm -rf /var/cache/apk/*
RUN apk add --no-cache supervisor mariadb-connector-c-dev
RUN mkdir -p /var/log/supervisor && \
    mkdir -p /etc/supervisor/conf.d && \
    touch /var/run/supervisor.sock && \
    chmod 777 /var/log/supervisor && \
    chmod 777 /var/run/supervisor.sock
RUN cp -f /opt/repo/tools/supervisord.conf /etc/supervisord.conf && \
    cp /opt/repo/tools/my_app.conf /etc/supervisor/conf.d/
RUN pip3 install -r requirement.txt
 
ENTRYPOINT ["/usr/bin/supervisord", "--nodaemon", "--configuration", "/etc/supervisord.conf"]

Debian版本

FROM harbor.paas.shein.io/helper/compile:latest AS clone
ARG REPO
ARG BRANCHNAME
RUN git clone --depth=100 -b $BRANCHNAME $REPO /repo 

FROM python:3.7.3 AS build
COPY --from=clone /repo /repo
RUN apt-get update -y && \
    apt-get install -y curl git && \
    apt-get install mysql-client  redis-server -y
RUN cp -r /repo /opt/repo && \        
    cd /opt/repo && \ 
    pip3 install  -r requirements.txt
RUN pip3 install awscli
RUN apt-get install supervisor -y  && \
    cp -f /opt/repo/conf/django.conf /etc/supervisor/conf.d/ && \
    cp -f /opt/repo/conf/redis.conf /etc/supervisor/conf.d/ && \
    cp -f /opt/repo/conf/supervisord.conf /etc/supervisor/supervisord.conf 
 
ENTRYPOINT ["/usr/bin/supervisord", "--nodaemon", "--configuration", "/etc/supervisord.conf"]

Docker 镜像示例解释

  1. 选择指定版本的python-alpine做基础镜像,轻量、消耗小。 如果有特殊需求,也可以选择ubuntu等其他基础镜像。
  2. 用supervisord管理web服务和其他后台进程,并且使用 --nodaemon方式启动supervisor,让其成为主进程。
    1. supervisord做主进程,容器crash重启概率大大降低,可以通过supervisord打到控制台的日志,了解其管理的多个服务的运行情况。
    2. supervisord默认以守护进程方式运行, --nodaemon 参数可使其前台运行,成为容器的主进程。
  3. 安装新的系统包时,使用 --no-cache命令,删除不必要的下载包和缓存内容,减小容器大小。
  4. 清理系统cache目录, 如  /var/cache/apk/*

Supervisor关键配置

[supervisord]
nodaemon=true              ; (start in foreground if true;default false)  与 ENTRYPOINT 中的 --nodaemon 二选一,前台运行supervisord
[supervisorctl]
redirect_stderr=true          ; redirect proc stderr to stdout (default false) 解注释官方的supervisor配置文件,stderr重定向到stdout
[include]
files = /etc/supervisor/conf.d/*.conf   ; supervisord管理的服务的配置文件,从指定的目录中加载

参考资料

https://blog.trifork.com/2014/03/11/using-supervisor-with-docker-to-manage-processes-supporting-image-inheritance/

上一篇:Supervisor修改配置文件后启动出错:Error: Cannot open an HTTP server: socket.error reported errno.EADDRNOTAVAIL


下一篇:supervisor 从安装到使用