Docker Lamp Centos7: '/bin/sh -c systemctl start httpd.service' 返回非零代码:1

Docker Lamp Centos7: '/bin/sh -c systemctl start httpd.service' returned a non-zero code: 1

我开始使用 docker 来自动化环境,然后我尝试构建一个简单的 LAMP 所以 Dockerfile 如下:

FROM centos:7

ENV container=docker

RUN yum -y swap -- remove systemd-container systemd-container-libs -- install systemd systemd-libs

RUN yum -y update; yum clean all; \
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]

RUN yum -y update && yum clean all
RUN yum -y install firewalld httpd mariadb-server mariadb php php-mysql php-gd php-pear php-xml php-bcmath php-mbstring php-mcrypt php-php-gettext

#Enable services
RUN systemctl enable httpd.service
RUN systemctl enable mariadb.service

#start services
RUN systemctl start httpd.service
RUN systemctl start mariadb.service

#Open firewall ports
RUN firewall-cmd --permanent --add-service=http
RUN firewall-cmd --permanent --add-service=https
RUN firewall-cmd --reload


EXPOSE 80
CMD ["/usr/sbin/init"]

所以当我构建图像时

docker build -t myimage .

然后当我 运行 代码时,我得到以下错误:

The command '/bin/sh -c systemctl start httpd.service' returned a non-zero code: 1

当我进入交互模式时(在RUN systemctl start httpd.service之后跳转命令并重新构建图像):

docker run -t -i myimage /bin/bash

尝试手动启动服务后 httpd 我得到以下错误:

Failed to get D-Bus connection: No connection to service manager.

所以,我不知道我做错了什么?

首先,欢迎来到Docker! :-) 大量 Docker 教程和文档是围绕 Ubuntu 容器编写的,但我也喜欢 Centos。

好的,这里有几件事要谈:

  1. 你 运行 对抗 a known issue with systemd-based Docker containers where they seem to need extra privileges to run, and even then lots of extra config is required to get them working. The Red Hat team are experimenting with some fixes (mentioned in comments) 但不确定它在哪里。

    如果你想尝试让它工作,these are the best instructions I've found,但我在过去几周里玩过几次,但还没有让它工作。

  2. 人们可能会说 "the real issue" 这里是 Docker 容器不应该被认为是 "mini Virtual Machine"。 Docker 是 designed to run one "root" process per container,容器系统使得将多个容器组合在一起变得很容易 - 它们占用的磁盘空间小,内存使用量小并且易于联网。

    这是一个blog post from Docker which gives some background on this. There's also the "Docker Fundamentals" docs on Dockerizing applications and Working with containers

    因此,可以说,继续您尝试在此处创建的设置的最佳方式(尽管一开始听起来可能更复杂)是将您的 "stack" 分解为您需要的服务,并且然后使用 docker-compose (introduction, documentation) 之类的工具根据需要创建单一用途的 Docker 容器。

    在你上面的例子中,你有两个服务,一个网络服务器和一个数据库服务器。因此,两个 Docker 容器应该可以正常工作,通过数据库网络连接连接在一起。以下是一些示例:

    如果您 运行 每个 Docker 容器一个服务,则不需要使用 systemd 来管理它们,因为 Docker 守护程序管理每个容器类别就像它是一个 Unix 进程。当进程死亡时,Docker 容器也死亡,这很重要,因为 Docker 服务器监控容器并可以自动重启它们,或者通知你。

这看起来更像是我的 docker-systemctl-replacement 适合的完美示例。它可以很容易地解释 "systemctl start httpd.service" 而无需周围有活动的 SystemD。我对一些数据库服务做了同样的事情,但不是特别是 mariadb.service - 也许你可以试一试。