You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker含httpd与memcached的镜像启动容器时memcached未自启的解决方法

问题根因
  • Dockerfile中重复定义ENTRYPOINT指令。按照Docker的运行规则,同一文件内书写多次ENTRYPOINT时,只有最后一条配置会生效,前面的配置会被完全覆盖。原配置先后写了httpd、memcached两组ENTRYPOINT,从机制上就无法同时拉起两个服务。
  • 多服务启动逻辑不符合容器运行规范。容器默认需要以前台常驻进程作为PID1维持生命周期,不能通过拆分多个ENTRYPOINT启动多个服务;且容器内默认没有完整的init运行环境,systemctl这类依赖systemd生态的命令无法正常执行,哪怕配置了enable/start指令也不会生效。
  • memcached启动参数书写不规范。原配置的memcached命令带了无意义的start参数,缺少-d后台运行标识,同时把监听IP直接放在命令末尾而非通过-l参数指定,这类错误写法会导致服务无法按预期拉起。
可行的配置方案

单容器内启动两个服务的核心逻辑是:容器启动时先把需要后台运行的memcached拉起,再把需要前台常驻的httpd设为PID1主进程,保证容器不会提前退出。根据实际场景可以选择两种实现方式:

轻量Shell脚本方案(无额外依赖,适合服务数量少的场景)

直接修改原Amazon Linux 2版本的Dockerfile,删除重复的ENTRYPOINT配置,通过启动脚本串联两个服务的启动流程:

FROM amazonlinux:2
MAINTAINER tian
# 原有软件安装步骤保持不变
RUN yum update -y && \
    yum install -y tar unzip wget procps telnet httpd libevent libevent-devel gcc make && \
    wget http://www.memcached.org/files/memcached-1.4.24.tar.gz && \
    tar xvzf memcached-1.4.24.tar.gz && \
    /memcached-1.4.24/configure --enable-64bit && \
    make && make install && \
    rm -rf memcached-1.4.24.tar.gz memcached-1.4.24

# 编写统一启动脚本
RUN echo '#!/bin/bash\n\
# 后台启动memcached,通过-l参数指定监听地址\n\
memcached -u nobody -m 512 -p 11211 -l 127.0.0.1 -d\n\
# 以前台模式启动httpd作为主进程,保证容器不退出\n\
exec /usr/sbin/httpd -D FOREGROUND' > /start.sh && chmod +x /start.sh

# 仅保留一个ENTRYPOINT指向启动脚本
ENTRYPOINT ["/start.sh"]
EXPOSE 80 11211

方案说明:

  • 脚本先执行memcached的后台启动命令,修正原有参数错误(去掉多余的start参数,加上-d后台标识,通过-l正确指定监听地址)
  • 最后通过exec命令启动httpd,让httpd成为PID1进程,保证容器能正常接收停止信号,不会出现进程僵死的问题。
  • 两个服务不会抢占前台运行位置:memcached作为后台进程运行,httpd作为主进程维持容器整个生命周期。

进程管理器方案(适合多服务扩展场景)

如果后续需要部署更多服务,可以引入supervisord作为统一的进程管理器,替代手写shell脚本,自动完成服务拉起、故障重启的工作。基于UBI7镜像的修改示例如下:

FROM registry.access.redhat.com/ubi7/ubi:latest
MAINTAINER tian
# 安装基础软件与supervisord
RUN yum update -y && \
    yum install -y unzip httpd wget telnet memcached libmemcached supervisor

# 编写supervisord配置,同时管理两个服务
RUN echo '[program:memcached]\n\
command=/usr/bin/memcached -u nobody -m 512 -p 11211 -l 127.0.0.1\n\
autostart=true\n\
autorestart=true\n\
\n\
[program:httpd]\n\
command=/usr/sbin/httpd -D FOREGROUND\n\
autostart=true\n\
autorestart=true' > /etc/supervisord.conf

# 仅保留一个ENTRYPOINT启动supervisord
ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]
EXPOSE 80 11211

方案说明:

  • supervisord本身作为PID1运行,不需要依赖系统自带的systemd,从根本上解决systemctl命令无法执行的问题
  • 配置中开启了autorestart,任意一个服务异常退出都会被自动拉起,比手写shell脚本的运行稳定性更高。

注意:不推荐在容器内通过systemctl管理服务,因为容器启动时没有加载systemd的运行环境,哪怕加了特权参数也会带来不必要的安全风险。

内容的提问来源于stack exchange,提问作者jlu-tianji

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.22 15:36:04