Wie lassen sich Berechtigungen für freigegebene Docker-Volumes (am besten) verwalten?


345

Ich habe eine Weile mit Docker herumgespielt und finde immer wieder das gleiche Problem, wenn ich mit persistenten Daten arbeite.

Ich erstelle mein VolumeDockerfile und mache es verfügbar oder verwende es --volumes-from, um einen Hostordner in meinem Container bereitzustellen .

Welche Berechtigungen sollte ich für das freigegebene Volume auf dem Host anwenden?

Ich kann mir zwei Möglichkeiten vorstellen:

  • Bisher habe ich allen Lese- / Schreibzugriff gewährt, damit ich aus dem Docker-Container in den Ordner schreiben kann.

  • Ordnen Sie die Benutzer vom Host dem Container zu, damit ich detailliertere Berechtigungen zuweisen kann. Ich bin mir nicht sicher, ob dies möglich ist und habe nicht viel darüber gefunden. Bisher kann ich den Container nur als Benutzer ausführen: docker run -i -t -user="myuser" postgresDieser Benutzer hat jedoch eine andere UID als mein Host myuser, sodass Berechtigungen nicht funktionieren. Ich bin mir auch nicht sicher, ob die Zuordnung der Benutzer Sicherheitsrisiken birgt.

Gibt es andere Alternativen?

Wie geht ihr Jungs / Mädels mit diesem Problem um?


Überprüfen Sie diese Antwort anhand einer ähnlichen Frage .
Batandwa

1
Sie könnten auch an diesem Thread interessiert sein, der dieses Thema ausführlich behandelt: groups.google.com/forum/#!msg/docker-user/cVov44ZFg_c/…
btiernay


Derzeit plant das Docker-Team nicht, eine native Lösung zum Mounten von Host-Verzeichnissen als Volume mit der angegebenen UID / GID zu implementieren. Siehe meinen Kommentar und Antworten zu diesem Thema: github.com/docker/docker/issues/7198#issuecomment-230636074
Quinn Comendant

Antworten:


168

UPDATE 2016-03-02 : Ab Docker 1.9.0 hat Docker Volumes benannt, die Nur-Daten-Container ersetzen . Die folgende Antwort sowie mein verlinkter Blog-Beitrag haben immer noch einen Wert in dem Sinne, wie man über Daten in Docker nachdenkt. Verwenden Sie jedoch benannte Volumes, um das unten beschriebene Muster anstelle von Datencontainern zu implementieren.


Ich glaube, der kanonische Weg, dies zu lösen, ist die Verwendung von Nur-Daten-Containern . Bei diesem Ansatz erfolgt der gesamte Zugriff auf die Volumendaten über Container, die -volumes-fromden Datencontainer verwenden, sodass die Host-UID / GID keine Rolle spielt.

Ein in der Dokumentation angegebener Anwendungsfall ist beispielsweise das Sichern eines Datenvolumens. Zu diesem Zweck wird ein anderer Container verwendet, um die Sicherung über durchzuführen tar, und er wird auch verwendet -volumes-from, um das Volume bereitzustellen. Ich denke, der entscheidende Punkt bei grok ist: Anstatt darüber nachzudenken, wie Sie mit den richtigen Berechtigungen auf die Daten auf dem Host zugreifen können, sollten Sie darüber nachdenken, wie Sie alles tun können, was Sie benötigen - Backups, Surfen usw. - über einen anderen Container . Die Container selbst müssen konsistente UID / GIDs verwenden, müssen jedoch nichts auf dem Host zuordnen und bleiben somit portabel.

Dies ist auch für mich relativ neu, aber wenn Sie einen bestimmten Anwendungsfall haben, können Sie dies gerne kommentieren, und ich werde versuchen, die Antwort zu erweitern.

UPDATE : Für den angegebenen Anwendungsfall in den Kommentaren haben Sie möglicherweise ein Bild some/graphitezum Ausführen von Graphit und ein Bild some/graphitedataals Datencontainer. Wenn man also Ports und dergleichen ignoriert, ist das DockerfileBild some/graphitedataso etwas wie:

FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
  && useradd -r -g graphite graphite
RUN mkdir -p /data/graphite \
  && chown -R graphite:graphite /data/graphite
VOLUME /data/graphite
USER graphite
CMD ["echo", "Data container for graphite"]

Erstellen und erstellen Sie den Datencontainer:

docker build -t some/graphitedata Dockerfile
docker run --name graphitedata some/graphitedata

Das some/graphiteDockerfile sollte auch die gleiche UID / GID erhalten, daher könnte es ungefähr so ​​aussehen:

FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
  && useradd -r -g graphite graphite
# ... graphite installation ...
VOLUME /data/graphite
USER graphite
CMD ["/bin/graphite"]

Und es würde wie folgt laufen:

docker run --volumes-from=graphitedata some/graphite

Ok, jetzt erhalten wir unseren Graphitcontainer und den zugehörigen Nur-Daten-Container mit dem richtigen Benutzer / der richtigen Gruppe (beachten Sie, dass Sie den some/graphiteContainer auch für den Datencontainer wiederverwenden können, indem Sie den Eintrag / cmd beim Ausführen überschreiben, ihn aber als haben separate Bilder IMO ist klarer).

Angenommen, Sie möchten etwas im Datenordner bearbeiten. Erstellen Sie einen neuen Container, um diese Aufgabe zu erledigen, anstatt das Mounten des Volumes an den Host zu binden und dort zu bearbeiten. Nennen wir es some/graphitetools. Erstellen wir auch den entsprechenden Benutzer / die entsprechende Gruppe, genau wie das some/graphiteBild.

FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of other deps added later
RUN groupadd -r graphite \
  && useradd -r -g graphite graphite
VOLUME /data/graphite
USER graphite
CMD ["/bin/bash"]

Sie können diesen DRY erstellen, indem Sie von some/graphiteoder some/graphitedatain der Docker-Datei erben oder anstatt ein neues Image zu erstellen, verwenden Sie einfach eines der vorhandenen (überschreiben Sie den Einstiegspunkt / cmd nach Bedarf).

Jetzt rennst du einfach:

docker run -ti --rm --volumes-from=graphitedata some/graphitetools

und dann vi /data/graphite/whatever.txt. Dies funktioniert perfekt, da alle Behälter denselben Graphitbenutzer mit passender UID / GID haben.

Da Sie niemals /data/graphitevom Host aus mounten , ist es Ihnen egal, wie die Host-UID / GID der UID / GID zugeordnet wird, die in den Containern graphiteund definiert ist graphitetools. Diese Container können jetzt auf jedem Host bereitgestellt werden und funktionieren weiterhin einwandfrei.

Das Schöne daran ist, dass graphitetoolses alle möglichen nützlichen Dienstprogramme und Skripte geben kann, die Sie jetzt auch portabel bereitstellen können.

UPDATE 2 : Nachdem ich diese Antwort geschrieben hatte, beschloss ich, einen vollständigeren Blog-Beitrag über diesen Ansatz zu schreiben . Ich hoffe, es hilft.

UPDATE 3 : Ich habe diese Antwort korrigiert und weitere Details hinzugefügt. Zuvor enthielt es einige falsche Annahmen zu Besitz und Dauerwellen. Der Besitz wird normalerweise zum Zeitpunkt der Datenträgererstellung zugewiesen, dh im Datencontainer, da zu diesem Zeitpunkt der Datenträger erstellt wird. Siehe diesen Blog . Dies ist jedoch keine Voraussetzung - Sie können den Datencontainer einfach als "Referenz / Handle" verwenden und den Besitz / die Dauerwellen in einem anderen Container über chown in einem Einstiegspunkt festlegen, der mit gosu endet, um den Befehl als richtigen Benutzer auszuführen. Wenn sich jemand für diesen Ansatz interessiert, kommentieren Sie ihn bitte und ich kann mit diesem Ansatz Links zu einem Beispiel bereitstellen.


35
Ich fürchte, dies ist keine Lösung, da Sie das gleiche Problem mit den Nur-Daten-Containern haben. Letztendlich verwenden diese Container vom Host freigegebene Volumes, sodass Sie weiterhin die Berechtigungen für diese freigegebenen Ordner verwalten müssen.
Xabs

2
Beachten Sie, dass ich möglicherweise den Datenordner von meinem Host aus bearbeiten muss (z. B. einen Testgraphitschlüssel löschen, meinen JIRA-Teststartordner löschen oder ihn mit der neuesten Produktionssicherung aktualisieren ...). Soweit ich aus Ihrem Kommentar weiß, sollte ich beispielsweise JIRA-Daten über einen dritten Container aktualisieren. Welche Berechtigungen würden Sie auf jeden Fall für einen neuen Datenordner anwenden /data/newcontainer? Ich dockergehe davon aus, dass Sie als Root ausgeführt werden (ist dies nicht möglich?). Gibt es auch Unterschiede bei diesen Berechtigungen, wenn die Daten direkt im Hauptcontainer oder über einen Nur-Daten-Container bereitgestellt werden ?
Xabs

2
Vielen Dank für Ihre ausführliche Antwort. Werde das testen, sobald ich die Chance habe. Außerdem gibt es nette Hinweise sowohl auf Ihren Blog- Beitrag als auch auf den über die Verwendung minimaler Bilder für Datencontainer .
Xabs

3
Das einzige Problem bei diesem Ansatz ist, dass es sehr einfach ist, einen Container versehentlich zu löschen. Stellen Sie sich vor, es ist Ihr Datencontainer. Ich denke (CMIIW) die Daten werden immer noch /var/lib/dockerirgendwo sein, aber immer noch ein großer Schmerz
lolski

3
"Sie können den Datencontainer einfach als" Referenz / Handle "verwenden und den Besitz / die Dauerwelle in einem anderen Container über Chown in einem Einstiegspunkt festlegen" ... @Raman: Dies ist der Abschnitt, der mich schließlich gerettet hat, nachdem ich zahlreiche Berechtigungsprobleme nicht hatte herausgefunden. Die Verwendung eines Einstiegspunktskripts und das Festlegen von Berechtigungen funktioniert bei mir. Vielen Dank für Ihre ausführliche Erklärung. Es ist das Beste, was ich bisher im Internet gefunden habe.
Vanderstaaij

59

Eine sehr elegante Lösung ist auf dem offiziellen Redis-Bild und allgemein auf allen offiziellen Bildern zu sehen.

Schritt für Schritt beschrieben:

  • Erstellen Sie Redis User / Group vor allem anderen

Wie in Dockerfile-Kommentaren zu sehen:

Fügen Sie zuerst unseren Benutzer und unsere Gruppe hinzu, um sicherzustellen, dass ihre IDs konsistent zugewiesen werden, unabhängig davon, welche Abhängigkeiten hinzugefügt werden

  • Installieren Sie gosu mit Dockerfile

gosu ist eine Alternative zu su/ sudofür ein einfaches Herunterfahren vom Root-Benutzer. (Redis wird immer mit redisBenutzer ausgeführt)

  • Konfigurieren Sie das /dataVolume und legen Sie es als Arbeitsverzeichnis fest

Durch Konfigurieren des / data-Volumes mit dem VOLUME /dataBefehl haben wir jetzt ein separates Volume, das entweder Docker-Volume sein oder an ein Host-Verzeichnis gebunden werden kann.

Wenn Sie es als workdir ( WORKDIR /data) konfigurieren, wird es zum Standardverzeichnis, in dem Befehle ausgeführt werden.

  • Fügen Sie die Docker-Entrypoint-Datei hinzu und legen Sie sie als ENTRYPOINT mit dem Standard-CMD-Redis-Server fest

Dies bedeutet, dass alle Containerausführungen über das Docker-Entrypoint-Skript ausgeführt werden. Standardmäßig lautet der auszuführende Befehl redis-server.

docker-entrypointist ein Skript, das eine einfache Funktion ausführt: Ändern Sie den Besitz des aktuellen Verzeichnisses (/ data) und wechseln Sie von rootzu redisBenutzer, um es auszuführen redis-server. (Wenn der ausgeführte Befehl kein Redis-Server ist, wird der Befehl direkt ausgeführt.)

Dies hat folgenden Effekt

Wenn das Verzeichnis / data an den Host gebunden ist, bereitet der Docker-Einstiegspunkt die Benutzerberechtigungen vor, bevor der Redis-Server unter redisBenutzer ausgeführt wird.

Dies gibt Ihnen die Gewissheit, dass es keine Einrichtung gibt, um den Container unter einer beliebigen Volume-Konfiguration auszuführen.

Wenn Sie das Volume für verschiedene Bilder freigeben müssen, müssen Sie natürlich sicherstellen, dass sie dieselbe Benutzer- / Gruppen-ID verwenden. Andernfalls übernimmt der neueste Container die Benutzerberechtigungen des vorherigen.


11
Die akzeptierte Antwort ist informativ, hat mich aber nur einen einwöchigen Weg der Frustration mit der Erlaubnis geführt, diese Antwort zu finden, die tatsächlich einen kanonischen Weg zur Lösung des Problems bietet.
m0meni


Damit? Wie mache ich das Volume im Docker beschreibbar? chownes im ENTRYPOINTSkript?
Gherman

34

Dies ist wohl nicht der beste Weg für die meisten Umstände, aber es wurde noch nicht erwähnt, vielleicht hilft es jemandem.

  1. Binden Sie das Mount-Host-Volume

    Host folder FOOBAR is mounted in container /volume/FOOBAR

  2. Ändern Sie das Startskript Ihres Containers, um die GID des Volumes zu finden, an dem Sie interessiert sind

    $ TARGET_GID=$(stat -c "%g" /volume/FOOBAR)

  3. Stellen Sie sicher, dass Ihr Benutzer zu einer Gruppe mit dieser GID gehört (möglicherweise müssen Sie eine neue Gruppe erstellen). In diesem Beispiel werde ich so tun, als würde meine Software als nobodyBenutzer ausgeführt, wenn ich mich im Container befinde. Daher möchte ich sicherstellen, dass sie nobodyzu einer Gruppe mit einer Gruppen-ID von gehörtTARGET_GID

  EXISTS=$(cat /etc/group | grep $TARGET_GID | wc -l)

  # Create new group using target GID and add nobody user
  if [ $EXISTS == "0" ]; then
    groupadd -g $TARGET_GID tempgroup
    usermod -a -G tempgroup nobody
  else
    # GID exists, find group name and add
    GROUP=$(getent group $TARGET_GID | cut -d: -f1)
    usermod -a -G $GROUP nobody
  fi

Ich mag dies, weil ich Gruppenberechtigungen auf meinen Host-Volumes leicht ändern kann und weiß, dass diese aktualisierten Berechtigungen im Docker-Container gelten. Dies geschieht ohne Erlaubnis oder Eigentumsänderungen an meinen Host-Ordnern / -Dateien, was mich glücklich macht.

Ich mag das nicht, weil davon ausgegangen wird, dass es keine Gefahr gibt, sich einer beliebigen Gruppe innerhalb des Containers hinzuzufügen, die zufällig eine gewünschte GID verwendet. Es kann nicht mit einer USERKlausel in einer Docker-Datei verwendet werden (es sei denn, dieser Benutzer verfügt vermutlich über Root-Rechte). Außerdem schreit es Hack Job ;-)

Wenn Sie Hardcore sein möchten, können Sie dies natürlich auf viele Arten erweitern - z. B. nach allen Gruppen in Subdateien, mehreren Volumes usw. suchen.


4
Ist dies darauf ausgerichtet , Dateien vom bereitgestellten Volume zu lesen ? Ich suche nach einer Lösung zum Schreiben von Dateien, ohne dass diese einem anderen Benutzer gehören als dem, der den Docker-Container erstellt hat.
ThorSummoner

Ich benutze diesen Ansatz seit dem 15. August. Alles war in Ordnung. Nur die Berechtigungen der im Container erstellten Dateien waren unterschiedlich. Beide Benutzer (innerhalb und außerhalb des Containers) haben die Eigentümer ihrer Dateien, aber beide hatten Lesezugriff darauf, da sie zu derselben Gruppe gehörten, die mit dieser Lösung erstellt wurde. Das Problem begann, als ein Anwendungsfall Schreibzugriff auf allgemeine Dateien erzwang. Ein größeres Problem war, dass das gemeinsam genutzte Volumen Git-Dateien hatte (es ist ein Volume zum Testen von Dev-Quelldateien im selben Produktionskontext). Git warnte vor Zugriffsproblemen auf den freigegebenen Code.
Yucer

Ich denke, ein besserer Grep für $TARGET_GIDwäre die Verwendung grep ':$TARGET_GID:', andernfalls, wenn der Container zB gid 10001 hat und Ihr Host 1000 ist, wird diese Prüfung bestanden, sollte es aber nicht.
Robhudson

16

Ok, dies wird jetzt in der Docker-Ausgabe Nr. 7198 verfolgt

Im Moment beschäftige ich mich mit Ihrer zweiten Option:

Ordnen Sie die Benutzer vom Host dem Container zu

Dockerfile

#=======
# Users
#=======
# TODO: Idk how to fix hardcoding uid & gid, specifics to docker host machine
RUN (adduser --system --uid=1000 --gid=1000 \
        --home /home/myguestuser --shell /bin/bash myguestuser)

CLI

# DIR_HOST and DIR_GUEST belongs to uid:gid 1000:1000
docker run -d -v ${DIR_HOST}:${DIR_GUEST} elgalu/myservice:latest

UPDATE Ich bin derzeit eher geneigt, Hamy zu antworten


1
verwenden Sie den Befehl id -u <username>, id -g <username>, id -G <username>die Benutzer - ID und Gruppen - ID eines bestimmten Benutzers , anstatt zu bekommen
lolski


15
Dies zerstört die Portabilität von Containern zwischen Hosts.
Raman

2
Das Docker-Problem Nr. 7198 ist zu dem Schluss gekommen, dass hierfür keine native Lösung implementiert wird. Siehe meinen Kommentar und Antworten unter github.com/docker/docker/issues/7198#issuecomment-230636074
Quinn Comendant


12

Genau wie Sie habe ich nach einer Möglichkeit gesucht, Benutzer / Gruppen vom Host auf Docker-Container abzubilden. Dies ist der kürzeste Weg, den ich bisher gefunden habe:

  version: "3"
    services:
      my-service:
        .....
        volumes:
          # take uid/gid lists from host
          - /etc/passwd:/etc/passwd:ro
          - /etc/group:/etc/group:ro
          # mount config folder
          - path-to-my-configs/my-service:/etc/my-service:ro
        .....

Dies ist ein Auszug aus meiner docker-compose.yml.

Die Idee ist, Benutzer- / Gruppenlisten (im schreibgeschützten Modus) vom Host in den Container zu mounten, damit der Container nach dem Start des UID-> Benutzernamens (sowie für Gruppen) mit dem Host übereinstimmt. Jetzt können Sie Benutzer- / Gruppeneinstellungen für Ihren Dienst im Container so konfigurieren, als ob er auf Ihrem Hostsystem funktioniert.

Wenn Sie Ihren Container auf einen anderen Host verschieben möchten, müssen Sie nur den Benutzernamen in der Dienstkonfigurationsdatei in den Namen ändern, den Sie auf diesem Host haben.


Dies ist eine großartige Antwort, sehr einfach, wenn Sie Container ausführen möchten, die Dateien auf einem Basissystem verarbeiten, ohne den Rest des Systems verfügbar zu machen.
icarito

Das ist meine Lieblingsantwort. Außerdem habe ich an anderer Stelle eine ähnliche Empfehlung mit dem Docker-Befehl run gesehen, bei dem Sie Ihren aktuellen Benutzernamen / Ihre aktuellen Gruppen über übergeben -u $( id -u $USER ):$( id -g $USER )und sich nicht mehr um den Benutzernamen kümmern müssen. Dies funktioniert gut für lokale Entwicklungsumgebungen, in denen Sie Dateien (z. B. Binärdateien) generieren möchten, auf die Sie standardmäßig Lese- / Schreibzugriff haben.
Matthewcummings516

5

Hier ist ein Ansatz, bei dem immer noch ein Nur-Daten-Container verwendet wird, der jedoch nicht mit dem Anwendungscontainer synchronisiert werden muss (in Bezug auf dieselbe UID / GID).

Vermutlich möchten Sie eine App im Container als Nicht-Root-USER ohne Login-Shell ausführen.

In der Docker-Datei:

RUN useradd -s /bin/false myuser

# Set environment variables
ENV VOLUME_ROOT /data
ENV USER myuser

...

ENTRYPOINT ["./entrypoint.sh"]

Dann in entrypoint.sh:

chown -R $USER:$USER $VOLUME_ROOT
su -s /bin/bash - $USER -c "cd $repo/build; $@"

5

Versuchen Sie für sichere und geänderte Root für Docker-Container einen Docker-Host verwenden --uidmapund --private-uidsOptionen

https://github.com/docker/docker/pull/4572#issuecomment-38400893

Aus --cap-dropSicherheitsgründen können Sie auch mehrere Funktionen ( ) im Docker-Container entfernen

http://opensource.com/business/14/9/security-for-docker

UPDATE- Unterstützung sollte kommendocker > 1.7.0

UPDATE- Version 1.10.0(2016-02-04) --userns-remapFlag hinzufügen https://github.com/docker/docker/blob/master/CHANGELOG.md#security-2


Ich verwende Docker 1.3.2 Build 39fa2fa (aktuell) und sehe weder Spuren der --uidmapnoch der --private-uidsOptionen. Sieht so aus, als hätte die PR es nicht geschafft und wurde nicht zusammengeführt.
Leo Gallucci

Es wird nicht im Kern zusammengeführt, wenn Sie möchten, können Sie es wie Patch verwenden. Jetzt nur noch einige Funktionen einschränken und Ihre Anwendung im Container von Nicht-Root-Benutzern ausführen.
umount

Juni 2015 und ich sehe nicht, dass dies in Docker 1.6.2 zusammengeführt wird. Ist Ihre Antwort noch gültig?
Leo Gallucci

1
Ausgabe noch offen. Entwickler sollten Unterstützung in Version 1.7 hinzufügen. (--root Option) github.com/docker/docker/pull/12648
umount

2
Es scheint, dass die Entwickler die Version erneut mit dieser Funktionalität verschoben haben. Docker-Entwickler "icecrime" sagt "We apparently do have so some of conflicting designs between libnetwork and user namespaces ... and something we'd like to get in for 1.8.0. So don't think we're dropping this, we're definitely going to take a break after all these, and see how we need to reconsider the current design and integration of libnetwork to make this possible. Thanks!" github.com/docker/docker/pull/12648 Ich denke, wir sollten die nächste stabile Version abwarten.
umount

4

Mein Ansatz besteht darin, die aktuelle UID / GID zu erkennen, dann einen solchen Benutzer / eine solche Gruppe im Container zu erstellen und das Skript unter ihm auszuführen. Infolgedessen stimmen alle von ihm erstellten Dateien mit dem Benutzer auf dem Host (dem Skript) überein:

# get location of this script no matter what your current folder is, this might break between shells so make sure you run bash
LOCAL_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# get current IDs
USER_ID=$(id -u)
GROUP_ID=$(id -g)

echo "Mount $LOCAL_DIR into docker, and match the host IDs ($USER_ID:$GROUP_ID) inside the container."

docker run -v $LOCAL_DIR:/host_mount -i debian:9.4-slim bash -c "set -euo pipefail && groupadd -r -g $GROUP_ID lowprivgroup && useradd -u $USER_ID lowprivuser -g $GROUP_ID && cd /host_mount && su -c ./runMyScriptAsRegularUser.sh lowprivuser"

3

Basisbild

Verwenden Sie dieses Bild: https://hub.docker.com/r/reduardo7/docker-host-user

oder

Wichtig: Dadurch wird die Portabilität von Containern zwischen Hosts zerstört .

1) init.sh

#!/bin/bash

if ! getent passwd $DOCKDEV_USER_NAME > /dev/null
  then
    echo "Creating user $DOCKDEV_USER_NAME:$DOCKDEV_GROUP_NAME"
    groupadd --gid $DOCKDEV_GROUP_ID -r $DOCKDEV_GROUP_NAME
    useradd --system --uid=$DOCKDEV_USER_ID --gid=$DOCKDEV_GROUP_ID \
        --home-dir /home --password $DOCKDEV_USER_NAME $DOCKDEV_USER_NAME
    usermod -a -G sudo $DOCKDEV_USER_NAME
    chown -R $DOCKDEV_USER_NAME:$DOCKDEV_GROUP_NAME /home
  fi

sudo -u $DOCKDEV_USER_NAME bash

2) Dockerfile

FROM ubuntu:latest
# Volumes
    VOLUME ["/home/data"]
# Copy Files
    COPY /home/data/init.sh /home
# Init
    RUN chmod a+x /home/init.sh

3) run.sh.

#!/bin/bash

DOCKDEV_VARIABLES=(\
  DOCKDEV_USER_NAME=$USERNAME\
  DOCKDEV_USER_ID=$UID\
  DOCKDEV_GROUP_NAME=$(id -g -n $USERNAME)\
  DOCKDEV_GROUP_ID=$(id -g $USERNAME)\
)

cmd="docker run"

if [ ! -z "${DOCKDEV_VARIABLES}" ]; then
  for v in ${DOCKDEV_VARIABLES[@]}; do
    cmd="${cmd} -e ${v}"
  done
fi

# /home/usr/data contains init.sh
$cmd -v /home/usr/data:/home/data -i -t my-image /home/init.sh

4) Bauen mit docker

4) Lauf!

sh run.sh

0

In meinem speziellen Fall habe ich versucht, mein Knotenpaket mit dem Knoten-Docker-Image zu erstellen, damit ich npm nicht auf dem Bereitstellungsserver installieren muss. Es funktionierte gut, bis ich außerhalb des Containers und auf dem Host-Computer versuchte, eine Datei in das Verzeichnis node_modules zu verschieben, das das Docker-Image des Knotens erstellt hatte, für das mir die Berechtigungen verweigert wurden, weil es Root gehörte. Ich erkannte, dass ich dies umgehen konnte, indem ich das Verzeichnis aus dem Container auf den Host-Computer kopierte. Über Docker-Dokumente ...

Auf den lokalen Computer kopierte Dateien werden mit der UID: GID des Benutzers erstellt, der den Docker-Befehl cp aufgerufen hat.

Dies ist der Bash-Code, mit dem ich den Besitz des Verzeichnisses geändert habe, das von und innerhalb des Docker-Containers erstellt wurde.

NODE_IMAGE=node_builder
docker run -v $(pwd)/build:/build -w="/build" --name $NODE_IMAGE node:6-slim npm i --production
# node_modules is owned by root, so we need to copy it out 
docker cp $NODE_IMAGE:/build/node_modules build/lambda 
# you might have issues trying to remove the directory "node_modules" within the shared volume "build", because it is owned by root, so remove the image and its volumes
docker rm -vf $NODE_IMAGE || true

Bei Bedarf können Sie das Verzeichnis mit einem zweiten Docker-Container entfernen.

docker run -v $(pwd)/build:/build -w="/build" --name $RMR_IMAGE node:6-slim rm -r node_modules

0

Versuchen Sie den folgenden Befehl, um den Ordner zwischen Docker-Host und Docker-Container freizugeben

$ docker run -v "$ (pwd): $ (pwd)" -i -t ubuntu

Das Flag -v stellt das aktuelle Arbeitsverzeichnis im Container bereit. Wenn das Hostverzeichnis eines bindgebundenen Volumes nicht vorhanden ist, erstellt Docker dieses Verzeichnis automatisch auf dem Host für Sie.

Es gibt jedoch zwei Probleme, die wir hier haben:

  1. Sie können nicht auf das bereitgestellte Volume schreiben, wenn Sie kein Root-Benutzer waren, da die freigegebene Datei einem anderen Benutzer im Host gehört.
  2. Sie sollten den Prozess in Ihren Containern nicht als Root ausführen, aber selbst wenn Sie als fest codierter Benutzer ausgeführt werden, stimmt er nicht mit dem Benutzer auf Ihrem Laptop / Jenkins überein.

Lösung:

Container: Erstellen Sie einen Benutzer, sagen Sie 'testuser'. Standardmäßig beginnt die Benutzer-ID bei 1000,

Host: Erstellen Sie eine Gruppe mit dem Namen 'testgroup' mit der Gruppen-ID 1000 und teilen Sie das Verzeichnis der neuen Gruppe (testgroup) mit


-5

Wenn Sie Docker Compose verwenden, starten Sie den Container im vorherigen Modus:

wordpress:
    image: wordpress:4.5.3
    restart: always
    ports:
      - 8084:80
    privileged: true

2
Dies könnte das Mounten von Volumes erleichtern, aber .. Wordpress im privilegierten Modus gestartet? Das ist eine schreckliche Idee - das verlangt, kompromittiert zu werden. wpvulndb.com/wordpresses/453
Colin Harrington
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.