1

I have the following piece of code which enables me to start a Docker container and subsequently run a command with Stdout and Stderr attached. The issue here is that it starts the container, but of course exits the container before I'm able to exec a command inside the container. How can I start the container and exec a command inside the container(in this case ls) and keep stdout and stderr attached without getting the "cannot exec in a stopped state" error message?

final String IMAGE = "centos";

final DockerClient docker = new 
DefaultDockerClient("unix:///var/run/docker.sock");

docker.pull(IMAGE);

final ContainerConfig containerConfig = ContainerConfig.builder()
    .image(IMAGE)
    .build();


final ContainerCreation creation = docker.createContainer(containerConfig);
final String id = creation.id();

docker.startContainer(id);

final String[] command = {"sh", "-c", "ls"};
final ExecCreation execCreation = docker.execCreate(
    id, command, DockerClient.ExecCreateParam.attachStdout(),
    DockerClient.ExecCreateParam.attachStderr());
final LogStream output = docker.execStart(execCreation.id());
final String execOutput = output.readFully();
Mads K
  • 847
  • 2
  • 14
  • 32

2 Answers2

3

You can change your RUN command in the container's Dockerfile to run a bash script which calls sleep 5000 at the end. Then your container will not stop immediately.

Robin Green
  • 32,079
  • 16
  • 104
  • 187
  • Instead of the ls command? But I'm not even able to invoke that command due to the container having exited a few milliseconds earlier. Also, sleeping just seems a tad dirty. – Mads K Nov 24 '18 at 16:56
  • 1
    Sorry, no, I meant instead of the `RUN` command in the `Dockerfile`. I edited my answer to clarify. – Robin Green Nov 24 '18 at 16:58
  • Ah, I see your point, so instead of invoking it from the script, I could invoke the command I want from the Dockerfile, but the issue is still that I don't have much control over the output, which I would get with execCreate et al. – Mads K Nov 24 '18 at 17:13
  • No, I was just suggesting you add a `sleep` to keep the container alive for a while. Then you could run the command you want from `execCreate`. – Robin Green Nov 24 '18 at 17:15
1

You can start the container with an infinite sleep loop

final ContainerConfig containerConfig = ContainerConfig.builder()
    .image(IMAGE)
    .cmd("sh", "-c", "while :; do sleep 1; done")
    .build();

(This is the example from the Spotify documentation)

Uku Loskit
  • 40,868
  • 9
  • 92
  • 93
  • Just tried with the sleep loop but still run into `cannot exec in a stopped state: unknown` – Mads K Nov 28 '18 at 08:39