1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

dockerdのみで自前Hello Dockerコンテナを立てる

1
Last updated at Posted at 2026-07-01

はじめに

普段使っているdockerコマンドの裏では、dockerdcontainerdruncが連携して動いている。今回は公式のインストールスクリプトやパッケージマネージャを使わず、静的バイナリからdockerdだけを取り出してインストールし、docker CLIを使わずcurlでAPIを直接叩いてコンテナを動かす。

Dockerのアーキテクチャ

Dockerはクライアント/サーバー型のアーキテクチャになっている。CLIのdockerコマンドはクライアントの一つで、実体はdockerdが公開するREST APIを叩いているだけである。

Dockerとは何か

Dockerのアーキテクチャ図

アーキテクチャ図に登場するRegistryはイメージを保管・配布するサーバーで、Docker Hubなどがこれにあたる。docker pullやdocker pushでは、dockerdがクライアントに代わってRegistryとの通信を行っている。DockerfileのFROM命令も指定したイメージが手元になければRegistryからpullする。今回はRegistryを使わずに完結させたいので、FROM scratchを使い、ベースイメージなしでコンテナを組み立てる。
dockerコマンドやDockerレジストリのパッケージがなくても、dockerdとAPIで通信できるHTTPクライアント(ここではcurl)があればコンテナは動く。
以下で確認する。

手順

1. dockerdをインストールする

パッケージマネージャや公式インストールスクリプトは使わず、静的バイナリから必要なバイナリのみを取り出す。テスト用途向けの方法で、アップデートも手動管理になるため通常は推奨されていない。環境はDebian安定版を使用。

バイナリを取得し、必要なもの(dockerd, containerd, containerd-shim-runc-v2, runc)を配置する。

$ mkdir -p ~/Work && cd ~/Work
$ curl -LO https://download.docker.com/linux/static/stable/x86_64/docker-XX.X.X.tgz  # バージョンは最新のものに
$ tar -xvf docker-XX.X.X.tgz
$ sudo cp docker/{dockerd,containerd,containerd-shim-runc-v2,runc} /usr/bin/

ネットワーク周りは最小構成にするため、設定ファイルで無効化する。

$ sudo mkdir -p /etc/docker
$ sudo tee /etc/docker/daemon.json <<'EOF'
{
    "userland-proxy": false,
    "iptables": false
}
EOF
$ sudo dockerd

2. Dockerfileを用意する

動作確認用に、1秒ごとに現在時刻を出力するプログラムを用意する。

// hello.c
#include <stdio.h>
#include <unistd.h>
#include <time.h>

int main(void)
{
    setbuf(stdout, NULL);
    while (1)
    {
        time_t now = time(NULL);
        struct tm *t = localtime(&now);
        printf("[%02d:%02d:%02d] hello\n", t->tm_hour, t->tm_min, t->tm_sec);
        sleep(1);
    }
    return (0);
}

FROM scratchで使うため、静的リンクでコンパイルする。

$ cc -static hello.c -o hello
# Dockerfile
FROM scratch
COPY hello /hello
CMD ["/hello"]

ビルドコンテキストとしてtarにまとめる。

$ tar -cvf hello_docker.tar hello Dockerfile

3. curlで動かす

dockerコマンドは使わず、Unixソケット越しのHTTPリクエストのみで進める。

イメージのビルドは/buildエンドポイントに先ほどのtarをそのまま送る。

$ sudo curl --unix-socket /var/run/docker.sock \
    -X POST "http://localhost/v1.45/build?t=hello" \
    -H "Content-Type: application/x-tar" \
    --data-binary @hello_docker.tar

イメージができたらコンテナを作成し、起動する。

# コンテナ作成
$ sudo curl --unix-socket /var/run/docker.sock \
    -X POST -H "Content-Type: application/json" \
    -d '{"Image": "hello"}' \
    "http://localhost/v1.45/containers/create?name=hello_container"
# => {"Id":"xxxxxxxx...","Warnings":null}

# 起動
$ sudo curl --unix-socket /var/run/docker.sock \
    -X POST "http://localhost/v1.45/containers/hello_container/start"

ログを見ると、docker runした場合と同様に動作していることが確認できる。

# ログを出力
$ sudo curl --unix-socket /var/run/docker.sock -X GET "http://localhost/v1.43/containers/hello-test/logs?stdout=true&stderr=true" --output -

エンドポイントの詳細はDocker Engine APIのリファレンスにまとまっている。

まとめ

dockerd本体のみをインストールし、docker CLIなしでAPIを直接叩くことで、CLIが内部で行っている「イメージのビルド」「コンテナの作成」「起動」がそれぞれ独立したHTTPリクエストであることを確認した。dockerコマンドはこのAPIに対するラッパーであり、実体はシンプルなREST APIである。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?