docker-compose
で systemctl
からの Apache の起動が上手く行かず (Failed to get D-Bus connection: Operation not permitted
が出てしまう) 、手動でコマンドを一つずつ確認しながら Docker 環境の検証をしてみることにしました。
ちなみに環境は Docker for Windows 下で、バージョンは以下の通りとします。
> docker --version
Docker version 20.10.2, build 2291f61
検証
まずは CentOS7 のイメージから起動します。ローカルに centos:7
が既にある状態とします。
> docker run -it centos:7 /bin/bash
これでコマンドを入れていきます。今回は httpd-devel
を入れます。
# yum -y update && yum -y install epel-release sudo less iproute openssh-clients httpd-devel
いくつか設定ファイルを除外。
# mv -i /etc/httpd/conf.d/autoindex.conf /etc/httpd/conf.d/autoindex.conf.org
# mv -i /etc/httpd/conf.d/userdir.conf /etc/httpd/conf.d/userdir.conf.org
# mv -i /etc/httpd/conf.d/welcome.conf /etc/httpd/conf.d/welcome.conf.org
現状ではサーバ名がないため、 /etc/httpd/conf/httpd.conf
に追記します。ついでにバージョン情報を出さない設定もその後に追記できるかどうかのテストとして入れておきます。
# echo ServerName www.example.com:80 >> /etc/httpd/conf/httpd.conf
# echo ServerTokens Prod >> /etc/httpd/conf/httpd.conf
ここまでは上手く行くことが分かっているので、ひとまず fix します。
# exit
最初に docker run -it
したときに --name
オプションを付けなかったため適当なイメージ名でコンテナが上がっている (ここでは仮に XXXXX_XXXXXXXX
とします) ことを Docker Desktop から確認 (docker ps
でも可)。
その名前を自分で指定した名前で commit します。
> docker commit XXXXX_XXXXXXXX httpd_test_man
OK。イメージに登録されました。
これで再度コンテナに入ります。
> docker run -it httpd_test_man /bin/bash
#
今回は commit 時に指定した名前 httpd_test_man
で入れました。
# systemctl enable httpd.service
Created symlink /etc/systemd/system/multi-user.target.wants/httpd.service, pointing to /usr/lib/systemd/system/httpd.service.
# systemctl start httpd.service
Failed to get D-Bus connection: Operation not permitted
まずは普通に systemctl
してみます。 enable
はできましたが、 start
しようとすると
Failed to get D-Bus connection: Operation not permitted
エラーが発生することが確認できました。
ここで再び exit
。
> docker run -d --privileged -p 8080:80 --name httpd_test_man httpd_test_man /sbin/init
今度はオプションを変更したり追加したりしました。
docker run
時のオプションを-it
から-d
に変更--privileged
追加-p 8080:80
でポートフォワーディング--name httpd_test_man httpd_test_man
でイメージ名指定 (-d
のときは付ける必要があるため)/sbin/init
実行
> docker exec -it httpd_test_man /bin/bash
これでコンテナに入ります。
]# systemctl start httpd
# systemctl status httpd
● httpd.service - The Apache HTTP Server
## 略
起動できました。
上でポートフォワーディングしたように、 127.0.0.1:8080
でコンテナの Apache にアクセスできることが確認できました。
続いて hosts に以下のように追記します。
192.0.2.1 www.example.com #自PCのIPを www.example.com として追記
同じ結果になることは分かっていますが念のため。 www.example.com:8080
でアクセスできました。
これでひとまず、コマンドにオプションを付けて systemctl
で Apache が起動できることは確認できました。
……そうすると、何故 docker-compose
だとダメなのか……(いくつかの記事に書いてある方法を試してもダメで嵌まり中)。
備考 (本題)
Dockerfile
まず以下のような Dockerfile を用意します。
FROM centos:7
## systemd
##ENV container docker
##RUN (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" ]
# yum install
RUN yum -y update && yum -y install \
epel-release \
sudo \
less \
# network ss (instaed of netstat)
iproute \
# ssh
openssh-clients \
# apache
httpd-devel
# move apache config
RUN mv -i /etc/httpd/conf.d/autoindex.conf /etc/httpd/conf.d/autoindex.conf.org && \
mv -i /etc/httpd/conf.d/userdir.conf /etc/httpd/conf.d/userdir.conf.org && \
mv -i /etc/httpd/conf.d/welcome.conf /etc/httpd/conf.d/welcome.conf.org
# add last
RUN echo ServerName www.example.com:80 >> /etc/httpd/conf/httpd.conf
RUN echo ServerTokens Prod >> /etc/httpd/conf/httpd.conf
# # httpd service
RUN systemctl enable httpd.service
RUN systemctl start httpd.service
CMD ["/sbin/init"]
EXPOSE 80
## CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
#EXPOSE 80
#CMD /usr/sbin/httpd -DFOREGROUND
# volume directory
RUN mkdir /workspace
docekr-compose.yml
続いて docekr-compose.yml
。
version: '3.8'
services:
elephant:
build: .
volumes:
- ./workspace:/workspace
# - /sys/fs/cgroup:/sys/fs/cgroup:ro
tty: true
ports:
- "8080:80"
entrypoint: bash -c "bash /workspace/entrypoint.sh && /bin/bash"
privileged: true
/workspace/entrypoint.sh
はブランクで。
検索して引っかかった記事ではこのようなやり方で上手く行った、というのがいくつか見受けられたのですが、今回は上手く行かず……。
参考
Failed to get D-Bus connection: Operation not permitted
- CentOS7のDockerコンテナでsystemctlを使えるようにする – Qiita
- Docker-composeでCentOS7のコンテナを立ち上げてhttpdサービスを起動してみた – 株式会社クイックのWebサービス開発blog
- CentOS7のコンテナでsystemctlを使うための方法 – Qiita
- DockerコンテナのCentOS7で 「Failed to get D-Bus connection: Operation not permitted」と出た時の対処方法 – Opensourcetechブログ
シェルの処理
FROM centos:7
ENV container docker
RUN (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" ]
CMD ["/usr/sbin/init"]
これを Dockerfile に入れてもダメでした。
systemctl を使用しないやり方
この方法も試しましたがダメでした。