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

我开始使用docker来自动化envorinments,然后我正在尝试构build一个简单的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"] 

所以当我build立的形象

 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. 你遇到了一个基于systemd的Docker容器的已知问题 ,他们似乎需要额外的权限来运行,甚至需要大量额外的configuration才能使它们工作。 红帽团队正在尝试一些修复(在评论中提到),但不知道在哪里。

    如果你想尝试让它工作, 这些是我find的最好的指示 ,但在过去的几个星期里我已经玩过好几次了,但还没有完成。

  2. 人们可能会说的“真正的问题”在于,Docker容器不应该被认为是“小型虚拟机”。 Docker被devise为每个容器运行一个“root”进程 ,而容器系统可以很容易地将多个容器组合在一起 – 它们在磁盘上很小,内存使用简单,易于联网。

    这里有一个来自Docker的博客文章,它提供了一些背景知识 。 还有关于Dockerizing应用程序和使用容器的“Docker Fundamentals”文档。

    所以可以说,最好的方式来进行你想要创build的设置(虽然听起来可能听起来比较复杂),就是把你的“堆栈”分解成你需要的服务,然后使用像docker-compose这样的工具, docker-compose ( 介绍 , 文档 )根据需要创build单一用途的Docker容器。

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

    • Symfony应用程序,nginx和MariaDB的例子
    • MariaDB + NodeJS的例子

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

这看起来更像是一个完美的例子,我的docker-systemctl-replacement将会适合。 它可以很容易地解释“systemctl start httpd.service”而没有一个活跃的SystemD。 我已经做了一些数据库服务,但不专门mariadb.service – 可能是你可以试试。