"docker-compose exec" und die Verzeichnisse (Verzeichnisse in Docker: Kleines Tutorial)

Moin,

ich bin jetzt auch mal durch das eine oder andere ältere Posting gegangen. Da gibt es dann immer wieder Probleme mit dem Kommando docker-cpmose exec. Gerade mit Paperless NGX ergibt sich doch immer wieder die Notwendigkeit, es auszuführen und regelmäßig gibt es dann Probleme mit den Verzeichnissen/Pfadnamen. Daraus abgeleitet werden dann Umstände, die so einfach nicht stimmen bzw in ein anderes Licht gerückt werden sollten.

Ich werde hier mal ein paar Beispiele zeigen, was es genau mit docker-compose exec und den Verzeichnisses auf sich hat. Ich wede das allerdings nicht mit docker-compose machen, sondern mit docker exec direkt. Der Grund ist einfach: mit docker braucht man keine yml Datei und muss sich auch nicht in dem Verzeichnis befinden, wo die yml Datei abgespeichert ist. Die folgenden Beispiele funktionieren daher auch dann, wenn man PLNGX per portainer installiert hat. Das macht für diesen kleinen Exkurs jedoch keinen Unterschied. Die Syntax lautet:

docker exec <container-name> <command> <parameter>

Damit wir keine Probleme mit den Rechten bekommen, hängen wir noch ein sudo davor.

sudo docker exec <container-name> <command> <parameter>

sudo steht für su „do“ oder auch switch user do, also: wechsel den Benutzer und dann mach was danach kommt. Alles was danach kommt wird dann in der Regel mit dem user root ausgeführt, der weit mehr Rechte hat als man selbst. Das soll erst mal genügen zu sudo.

Mein Container heißt übrigens Paperless-NGX. Wer das mal nachvollziehen möchte muss natürlich seinen Containernamen angeben.

Ich logge mich jetzt einfach mal auf mein Synology NAS im ´Terminal-Modus an:

prompt>ssh huebi@workstation
huebi@workstation's password:

Using terminal commands to modify system configs, execute external binary
files, add files, or install unauthorized third-party apps may lead to system
damages or unexpected behavior, or cause data loss. Make sure you are aware of
the consequences of each command and proceed at your own risk.

Warning: Data should only be stored in shared folders. Data stored elsewhere
may be deleted when the system is updated/restarted.

huebi@WorkStation:~$

Nachdem ich mich nun eingeloggt habe, schau ich einfach mal, in welchem Verzeichnis ich mich befinde. Das kann man mit dem Kommando pwd (print working directory) herausbekommen.

huebi@WorkStation:~$ pwd
/var/services/homes/huebi
huebi@WorkStation:~$

Das kann je nach System auch etwas anders aussehen. Auf meinem NAS befinde ich mich also direkt nach dem Einloggen in meinem home-Verzeichnis.

Jetzt rufen wir was Kommando mal über docker auf:

huebi@WorkStation:~$ sudo docker exec Paperless-NGX pwd
/usr/src/paperless/src
huebi@WorkStation:~$

Überraschung! Ich befinde mich nicht mehr in meinem home-Verzeichnis. Wirklich nicht?

huebi@WorkStation:~$ pwd
/var/services/homes/huebi
huebi@WorkStation:~$

Doch, schon. Wenn ich docker-exec ausführe, wird nicht einfach nur das Komnmando gestartet, sondern ich bewege mich erst in den Container hinein und führe dort das entsprechende Kommando aus. Und in einem Container kann die Umgebung - also auch die Verzeichnisstruktur - eine ganz andere sein als außerhalb. Wenn das Kommando ausgeführt worden ist, verlasse ich den Container wieder und befinde mich in der Umgebung meines NAS wieder, so als wäre nicht passiert. Jetzt schauen wir uns mal an, was sich so in meinem home Verzeichnis befindet.

huebi@WorkStation:~$ ls -la
total 0
drwxrwxrwx+ 1 huebi users           70 Oct 20 20:01  .
drwxrwxrwx+ 1 root  root            42 Aug 19 21:11  ..
drwxrwxrwx+ 1 root  root            16 Sep 20 17:24  @eaDir
drwxrwxrwx+ 1 root  root            22 Oct  5 00:15 '#recycle'
drwxrwxrwx+ 1 huebi users           32 Oct 20 20:01  rescueplngx
drwxrwxrwx+ 1 root  StorageAnalyzer 44 Oct 20 00:30  synoreport
huebi@WorkStation:~$

Und wie sieht das innerhalb des Containers aus?

huebi@WorkStation:~$ sudo docker exec Paperless-NGX ls -la
total 16
drwxr-xr-x 1 paperless 1000  250 Aug 23 03:47 .
drwxr-xr-x 1 paperless 1000  106 Sep 26 12:00 ..
drwxr-xr-x 1 paperless 1000  100 Aug 15 15:42 docker
drwxr-xr-x 1 paperless 1000  822 Aug 23 03:47 documents
drwxr-xr-x 1 paperless 1000  450 Aug 23 03:52 locale
-rwxr-xr-x 1 paperless 1000  253 Aug 23 03:47 manage.py
drwxr-xr-x 1 paperless 1000  422 Aug 23 03:47 paperless
drwxr-xr-x 1 paperless 1000  242 Aug 23 03:47 paperless_mail
drwxr-xr-x 1 paperless 1000   94 Aug 23 03:47 paperless_tesseract
drwxr-xr-x 1 paperless 1000   76 Aug 23 03:47 paperless_text
drwxr-xr-x 1 paperless 1000   76 Aug 23 03:47 paperless_tika
-rw-r--r-- 1 paperless 1000 5222 Aug 23 03:28 requirements.txt
-rw-r--r-- 1 paperless 1000  922 Aug 23 03:47 setup.cfg
huebi@WorkStation:~$

Wie man sieht sieht es hier gaaaaanz anders aus. Und jetzt wird auch der Grund klar, warum manche Kommandos nicht zu funktionieren scheinen, zB sudo docker exec Paperless-NGX document_exporter /volume1/docker/paperlessngx/export -z. Der Grund warum das nicht klappt sollte jetzt klar sein: der angegeben Verzeichnisname existiert nicht in docker, sondern nur im NAS selbst. Was sich im Container befindet steht ja schon oben. Schauen wird doch mal was sich einen Ebene höher befindet:

huebi@WorkStation:~$ sudo docker exec Paperless-NGX ls .. -la
total 4
drwxr-xr-x 1 paperless  1000  106 Sep 26 12:00 .
drwxr-xr-x 1 root      root    18 Aug 15 15:42 ..
drwxr-xr-x 1 paperless users   20 Sep 26 12:00 .cache
drwx------ 1 paperless users   28 Oct 21 17:56 consume
drwxr-xr-x 1 paperless users  170 Oct 21 17:56 data
drwxr-xr-x 1 paperless users  210 Oct 21 17:57 export
-rw-r--r-- 1 paperless  1000 1351 Aug 15 15:40 gunicorn.conf.py
drwxr-xr-x 1 paperless users   38 Oct 21 17:56 media
drwxr-xr-x 1 paperless  1000  250 Aug 23 03:47 src
drwxr-xr-x 1 paperless  1000  296 Aug 23 03:50 static
huebi@WorkStation:~$

Aha. Eine Ebene höher befindet sich also das Export Verzeichnis. Wenn wir also dem document_exporter ein Verzeichnis mitgeben möchten, dann müssen wir ihm ein Verzeichnis nennen, was auch im Container exitiert. Und wie gesehen landen wir nach docker exec im verzeichnis src, und von dort müssen wir eine Ebene nach oben um dann in das Verzeichnis export gehen zu können. Und nochmals: alles was nach docker exec kommt, wird im angegeben Container ausgeführt.

Es ist daher nicht richtig, dass man dem document_exporter keinen absoluten Pfad angeben kann. Das kann man durchaus tun. /usr/src/paperless/export wäre zb ein gültiger absoluter Pfad, weil er im Container existiert. Ausserhalb des Containers ist der Inhalt dieses Ordners aber (bei mir) unter /volume1/docker/paperlessngx/export ansprechbar. Es ist derselbe Ort im NAS, aber in der Umgebung des NAS heißt er halt anders als im Container.

Wie die Verzeichnisse heißen kriegt man natürlich auch ohne pwd und ls heraus. Das steht schlicht und ergreifend in der yml Datei:

    volumes:
      - /volume1/docker/paperlessngx/data:/usr/src/paperless/data
      - /volume1/docker/paperlessngx/media:/usr/src/paperless/media
      - /volume1/docker/paperlessngx/export:/usr/src/paperless/export
      - /volume1/consume:/usr/src/paperless/consume

Links vom Doppelpunkt steht der Name wie es in der NAS Umgebung heißt, rechts vom Doppelpunkt wie es im Container heißt. Und wenn man sich in den Container begibt und dort etwas ausführt, muss man auch mit den Pfaden wie sie im Container existieren arbeiten. Und dann ist es egal, ob man da relativ oder absolut arbeitet.

Ich hoffe es ist jetzt etwas klarer, wann welcher Pfadname zu benutzen ist. Er muss halt in der Umgebung in der man sich befindet, existieren.

3 „Gefällt mir“

Danke für diesen ausführlichen Beitrag! Ich versuche mal, dass discourse ihn automatisch vorschlägt, wenn eine Frage dazu getippt wird :wink: