如何扩展ghostfolio镜像,后台运行Redis并保留原CMD前台执行?
背景
- 我想扩展Dockerfile,安装一个能在后台运行的程序。
- 部署在fly.io上,没法用docker-compose。
- 运行环境是低内存VM,不想用Supervisord这类有额外开销的工具。
问题
ghostfolio/ghostfolio的Dockerfile结尾是:
CMD [ "/ghostfolio/entrypoint.sh" ]
我想基于这个基础镜像扩展,同时运行Redis,示例如下:
FROM ghostfolio/ghostfolio:latest USER root RUN apt-get update && apt-get install -y --no-install-suggests redis-server && rm -rf /var/lib/apt/lists/* USER node CMD redis-server --requirepass "$REDIS_PASSWORD" & ???
我可以手动从基础镜像复制/ghostfolio/entrypoint.sh,但上游镜像如果变更可能会导致部署失败。请问怎么在后台运行redis-server的同时,把基础镜像的CMD作为前台进程执行?
方法1:自定义entrypoint脚本(推荐)
这种方式不依赖上游镜像的CMD硬编码内容,即使后续上游变更也能适配:
- 在Dockerfile同目录下创建
custom-entrypoint.sh脚本:
#!/bin/sh # 后台启动Redis redis-server --requirepass "$REDIS_PASSWORD" & # 调用原镜像的entrypoint,并让它成为容器的PID 1(保证信号能正确传递) exec /ghostfolio/entrypoint.sh
- 在Dockerfile里复制脚本并配置为ENTRYPOINT:
FROM ghostfolio/ghostfolio:latest USER root RUN apt-get update && apt-get install -y --no-install-suggests redis-server && rm -rf /var/lib/apt/lists/* # 复制并赋予执行权限 COPY custom-entrypoint.sh /usr/local/bin/ RUN chmod +x /usr/local/bin/custom-entrypoint.sh USER node ENTRYPOINT ["/usr/local/bin/custom-entrypoint.sh"]
方法2:直接在CMD里串联命令
如果不想额外添加脚本,也可以直接用shell语法实现,缺点是依赖上游CMD固定为/ghostfolio/entrypoint.sh:
FROM ghostfolio/ghostfolio:latest USER root RUN apt-get update && apt-get install -y --no-install-suggests redis-server && rm -rf /var/lib/apt/lists/* USER node CMD redis-server --requirepass "$REDIS_PASSWORD" & exec /ghostfolio/entrypoint.sh
关键注意点
- 一定要用
exec:它会把原entrypoint进程替换成容器的PID 1,这样容器停止时,原程序能收到正确的终止信号,避免出现僵尸进程。 - Redis配置可按需调整:比如需要自定义配置文件的话,可在启动命令后加
--config /path/to/redis.conf参数。
内容的提问来源于stack exchange,提问作者Aaron Brager
相关产品推荐
相关产品推荐

