私は、 "-opt/odoo /"ディレクトリに odoo が付いたコンテナを持っています。
「/etc/init.d/odoo-server」上のinitスクリプト
#!/bin/bash
### BEGIN INIT INFO
# Provides: odoo
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start openerp daemon at boot time
# Description: Enable service provided by daemon.
# X-Interactive: true
### END INIT INFO
## more info: http://wiki.debian.org/LSBInitScripts
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin
DAEMON=/opt/odoo/openerp-server
NAME=odoo
DESC=odoo
CONFIG=/etc/odoo-server.conf
LOGFILE=/var/log/odoo/odoo-server.log
PIDFILE=/var/run/${NAME}.pid
USER=odoo
export LOGNAME=$USER
test -x $DAEMON || exit 0
set -e
function _start() {
start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER:$USER --background --make-pidfile --exec $DAEMON -- --config $CONFIG --logfile $LOGFILE
}
function _stop() {
start-stop-daemon --stop --quiet --pidfile $PIDFILE --oknodo --retry 3
rm -f $PIDFILE
}
function _status() {
start-stop-daemon --status --quiet --pidfile $PIDFILE
return $?
}
case "$1" in
start)
echo -n "Starting $DESC: "
_start
echo "ok"
;;
stop)
echo -n "Stopping $DESC: "
_stop
echo "ok"
;;
restart|force-reload)
echo -n "Restarting $DESC: "
_stop
sleep 1
_start
echo "ok"
;;
status)
echo -n "Status of $DESC: "
_status && echo "running" || echo "stopped"
;;
*)
N=/etc/init.d/$NAME
echo "Usage: $N {start|stop|restart|force-reload|status}" >&2
exit 1
;;
esac
exit 0
それから私はします
root@cca438c81a87:/# update-rc.d odoo-server defaults
Adding system startup for /etc/init.d/odoo-server ...
/etc/rc0.d/K20odoo-server -> ../init.d/odoo-server
/etc/rc1.d/K20odoo-server -> ../init.d/odoo-server
/etc/rc6.d/K20odoo-server -> ../init.d/odoo-server
/etc/rc2.d/S20odoo-server -> ../init.d/odoo-server
/etc/rc3.d/S20odoo-server -> ../init.d/odoo-server
/etc/rc4.d/S20odoo-server -> ../init.d/odoo-server
/etc/rc5.d/S20odoo-server -> ../init.d/odoo-server
Docker startでdocker startを起動すると、odoo-serverが起動せず、docker /etc/init.d/odoo-server start内で実行すると、正常に動作します...
何が起こっている?
Dockerコンテナには通常、機能するinitシステムがありません。単一のサービスを実行しているだけなら、それを開始するだけです。
より複雑なものが必要な場合は、 supervisord または runit を参照してください。
コンテナは仮想マシンではありません。
本格的な動作のように動作するDockerイメージを探している場合VM init systemの場合は、 phusion baseimage を見てください。
今、私は数時間の作業でバグを追跡しました。
Debianシステムのメインデーモンスターター/テスター/ストッパーツールであるstart-stop-daemon
が、/proc/<pid>/exe
のデーモンプロセスの仮想ソフトリンクを調べてデーモンの存在を確認する問題の理由開始されたプロセスのバイナリイメージを指す必要があります)。
さて、問題は、Dockerではこのソフトリンクがデフォルトで機能しないことです。これは、Dockerがデフォルトのインストールで厳密なセキュリティポリシーを使用する必要があるためです(主に未確認のソフトウェアを実行するために使用されます)。
タスクには多くの回避策があり、コンテナの特権設定を変更する必要があるものと、そうでないものがあります。 2つの例:
start-stop-daemon
フラグと--test
フラグの両方を使用して--exec
を使用しないように初期化スクリプトを変更します--cap-add=SYS_ADMIN
コマンドにdocker run
オプションを指定して、Dockerコンテナーを起動します(Dockerコンテナーにsysadm権限は付与されません。生産的な使用のための予防策にすぎない可能性があります)。これらの隣にあるsystemd
もdockerでは機能しませんが、おそらくdockerのsystemdの欠点です。 systemd
の代わりに、 pstart を使用できます。
追記:Docker開発者/支持者は、「コンテナはVMではない」などとよく言っています。しかし、日常の経験では、2つの間にそれほど大きな違いはありません。ソフトウェアの生産的なDockerの使用には、少なくともVPSのような機能の最小限のサポートが確実に役立つでしょう。うまくいけば、ドッカーの開発も近い将来、この方向に向けて努力を集中させるでしょう。
サービスが開始されていないのは、/usr/sbin/policy-rc.d
が101コードを返すことが原因であることがわかりました。
参照: http://jpetazzo.github.io/2013/10/06/policy-rc-d-do-not-start-services-automatically/
そしてDockerはそれをコンテナで101を返すように設定しました。
そのため、ビルド時にスクリプトが機能するように変更して、build.sh
をDockerfile
で実行し、以下のスクリプトを実行できます。
cat << EOF > /usr/sbin/policy-rc.d
#!/bin/sh
# For most Docker users, "apt-get install" only happens during "docker build",
# where starting services doesn't work and often fails in humorous ways. This
# prevents those failures by stopping the services from attempting to start.
# exit 101
exit 0
EOF