"docker ps" aufrufen

krgewb

Top Contributor
Ich schaffe es nicht, mit meiner Anwendung "docker ps" auszuführen. Mit meiner anderen Anwendung funktioniert es aber.

Java:
    @Transactional
    public String executeDockerPs() {

        boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
        if (isWindows) {
            return null;
        }

        try {
            Process process = Runtime.getRuntime().exec("docker ps");

            StringBuilder output = new StringBuilder();

            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line;
            while ((line = reader.readLine()) != null) {
                output.append(line).append("\n");
            }

            int exitVal = process.waitFor();
            if (exitVal == 0) {
                return output.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return null;
    }

In meinem Start-Stop-Skript steht bereits:
Java:
--mount 'type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock' \

Fehlermeldung:
Code:
java.io.IOException: Cannot run program "docker": error=2, No such file or directory
 
yup, da fehlt einfach nur ein apt update und apt install docker -y (das linkt dann Docker richtig) vorher.

Viel Rätselraten hier bei den spärlichen Infos.
 
Das ist richtig. Das ist ein TCP-Socket. Aber der Container ist hierbei in der Funktion des Clients und der Host in der Funktion des Servers.

Ich weiß, dass du zwar keinen Bildungsauftrag hast, aber deshalb sollte man Anfängern nicht wissentlich etwas Falsches erzählen.
 
Wobei das mit dem "wissentlich" nehme ich zurueck, ich glaube das stimmt einfach nicht.

---

Um noch etwas produktives beizutragen, seit 1.5 gibt es den ProcessBuilder welcher etwas komfortabler sein kann als direkt exec aufzurufen.

Wenn du dann noch Java 9+ hast, kannst du auch sehr billig die gesamte Ausgabe des Kommandos auslesen:

Java:
byte[] rawOutput = process.getInputStream().readAllBytes();
String output = new String(rawOutput, StandardCharsets.UTF_8);

Beachte dabei aber immer dass denn der Prozess den Stream nicht schlieszt, haengt dein Programm an der Stelle.

Eine weitere, vielleicht etwas ueble, Variante waere dass man die Umgebung nutzt um das entsprechende Programm zu finden:

Java:
Process process = Runtime.getRuntime().exec("/usr/bin/env docker ps");

env ist immer unter /usr/bin/ verfuegbar und durchsucht die Umgebung nach dem entsprechenden Programm, spielt also keine Rolle ob das dann unter /bin/, /usr/bin/, /usr/local/bin/, oder irgendwo anders liegt solange die Umgebung korrekt konfiguriert ist um dies zu finden. Der gleiche Mechanismus wird bei Skell-Skripten eingesetzt fuer die Shebang:

Code:
#!/usr/bin/env bash
 
Code:
SHO:~ # whereis docker
docker: /usr/bin/docker /etc/docker /usr/share/man/man1/docker.1.gz
 
Jetzt geht es. In der Datei namens Dockerfile muss stehen:
Code:
RUN apt-get update && apt-get install -y docker.io && apt-get clean && rm -rf /var/lib/apt/lists/*
 
Ich habe ein Start-Stop-Skript für eine meiner Anwendungen. Nun will ich ein Java-Programm schreiben, das die Datei ausführt. Das könnte so aussehen:

Java:
    @Transactional
    public String executeCommand() {

        boolean isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows");
        if (isWindows) {
            return null;
        }

        try {
            Process process = Runtime.getRuntime().exec("/opt/docker/abc/video/services/user_interface_2/start_stop_user_interface_2.sh");

            StringBuilder output = new StringBuilder();

            BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line;
            while ((line = reader.readLine()) != null) {
                output.append(line).append("\n");
            }

            int exitVal = process.waitFor();
            if (exitVal == 0) {
                return output.toString();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return null;
    }

Nur leider funktioniert das nicht.
 
Ja nach Distribution, oder was der Nutzer installiert hat muss es mindestens eine Shell geben:
/bin/bash
/bin/sh
/bin/zsh
/bin/fish
sind so die üblichsten und sind meisten als link im Ordner /bin zu finden

Ein Shebang ist die erste Zeile im Script, also bspw: #!/bin/bash - ist also ein Zeiger auf die Shell, mit welcher des Terminal das Script ausführen soll.
Vermutlich führt das der Processbuilder aber nicht so aus wie ein Linux-Terminal. Deshalb musst du das selbst machen. Was du ausführen musst wäre demnach bspw:
...exec("/bin/bash /opt/docker/abc/video/services/user_interface_2/start_stop_user_interface_2.sh");

Du kannst natürlich auch ein Terminal starten und das Script als Parameter übergeben. Dann passiert aber das Gleiche wie in Windows(cmd) - es erscheint ein (schwarzes) Fenster.
 
Zuletzt bearbeitet:

Zurück
Oben