🤡

dockerのコンテナの中からホストのdockerコマンドを実行する

2024/05/28に公開

コード

ホストの/var/run/docker.sockをコンテナの/var/run/docker.sockにマウントしてやればできます。

FROM almalinux:9

USER root
RUN dnf update -y
RUN dnf install -y cronie logrotate dnf-plugins-core
RUN dnf config-manager --add-repo=https://download.docker.com/linux/centos/docker-ce.repo
RUN dnf install -y docker-ce

CMD tail -f /dev/null
services:
  docker:
    build:
      context: services/docker/
    container_name: docker_container
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

コードはAlmalinuxですが/var/run/docker.sockをコンテナにマウントするという発想はなんでも使えると思います。

compose使ってなくてrunするなら

docker run -v /var/run/docker.sock:/var/run/docker.sock ....

のようにすればOKですね。

WEBアプリのコンテナ群を試してて、logrotate用のコンテナから、ログをローテートした後にhttpdを再起動する方法を模索してて発見しました。

Linuxのソケットって面白いですね。

https://forums.docker.com/t/how-can-i-run-docker-command-inside-a-docker-container/337

ubuntu

ubuntuでも試したのでコード置いておきます。(2024/05/29追記)

FROM ubuntu:24.04

USER root
RUN apt-get update -y
RUN apt-get install -y ca-certificates curl
RUN install -m 0755 -d /etc/apt/keyrings
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
RUN chmod a+r /etc/apt/keyrings/docker.asc

RUN echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  tee /etc/apt/sources.list.d/docker.list > /dev/null
RUN apt-get update -y

RUN apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

CMD tail -f /dev/null

docker-compose.ymlは同じで大丈夫です。

systemctlとの併用は無理っぽい

今回このコンテナはlogrotate用コンテナで、最近のlogrotateはcronを使わずlogrotate.timersystemctlで動かしてローテートしています。

$ systemctl status logrotate.timer

● logrotate.timer - Daily rotation of log files
     Loaded: loaded (/usr/lib/systemd/system/logrotate.timer; enabled; preset: enabled)
     Active: active (waiting) since Sun 2024-03-24 16:42:17 JST; 2 months 5 days ago
      Until: Sun 2024-03-24 16:42:17 JST; 2 months 5 days ago
    Trigger: Thu 2024-05-30 00:00:00 JST; 8h left
   Triggers: ● logrotate.service
       Docs: man:logrotate(8)
             man:logrotate.conf(5)

Notice: journal has been rotated since unit was started, output may be incomplete.

dockerでsystemctlを使うにはdocker起動時にprivileged: truecommand: /sbin/initを指定してやれば使えるのですが、こうするとdockerが起動してしまい、volumesでマウントした/var/run/docker.sockが上書きされてしまいます。

FROM ubuntu:24.04

...

# 追記
RUN apt-get install -y init systemd

# 削除
# CMD tail -f /dev/null
services:
  docker:
    build:
      context: services/docker/
    container_name: docker_container
    # 追記
    privileged: true
    command: /sbin/init
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

これだとダメでしたね。dockerをsystemctlから削除してみましたが、volumeが作られるタイミングの問題なのか期待通り動きませんでした。

RUN systemctl disable docker.service
RUN systemctl disable docker.socket

Discussion