最近DockerをREST APIで操作していて色々躓いています。
なんとかChat-GPTの力を借りてやっていっています。
今回は、作業しているコンテナから別のコンテナに対して任意のファイルを実行させようとしたときに詰まったことについて紹介していきたいと思います。
何に詰まったかというと、
自分のコンテナ→相手のコンテナのファイル
の実行でPHPのexec関数を用いて
exec('docker exec コンテナID コマンド');
としていました。
が、まさかのPermission deniedされてしまいます。対象のコンテナ内のファイルの権限が777ではないため、権限不足になってしまいます。
今回は自分がやった対処法について話したいと思います。
素直にDockerのREST APIのexec用のAPIを叩きましょう
Dockerにはコンテナでコマンドを実行させるためのAPIが備わっています。
素直にそれを使いましょう。
使い方は
//host.docker.internalはホストOS上にコンテナを立てたいときに用います。場合によって変えましょう
$execUrl = "http://host.docker.internal:2375/containers/{コンテナID}/exec";
$execParam = [
"AttachStdout" => true,
"AttachStderr" => true,
"Cmd" => [
"bash", "-c", "実行したいコマンド"
]
];
$response = Http::withHeaders(['Content-Type' => 'application/json'])
->post($execUrl, $execParam);
$array = json_decode($response->body(), true);
$execId = $array['Id'];
これで、コンテナでのexecをしたときのIDが生成されます。
次に、このコンテナIDのコードを実行しましょう。
// コマンドを実行
$startResponse = Http::post("http://host.docker.internal:2375/exec/$execId/start", [
"Detach" => false,
"Tty" => true
]);
これで、コードが実行されました。コードの実行結果を取得したい際は、
$startResponse->body()
で取得できます。
ただこれ自体は問題があります。ログに出力されるものしか取得できない点です。
さらに、もし仮に実行するソースコードが間違えていてもエラーメッセージは取得できません。
functin test{
console.log('Hello World');
}
test();
では、Hello worldがbodyに格納されているのですが、もし仮にこのコードが間違えていたとしても、エラー文は取得できません。
そのへんはまだ自分も解決することができていないので、もし解決できたら記事にしたいと思います。
よろしくお願いします。