Jaki jest (najlepszy) sposób zarządzania uprawnieniami do udostępnionych woluminów Docker?

345

Od jakiegoś czasu bawię się Dockerem i ciągle znajduję ten sam problem, gdy mam do czynienia z trwałymi danymi.

Tworzę mój Dockerfilei udostępniam wolumin lub używam --volumes-fromdo zamontowania folderu hosta w moim kontenerze .

Jakie uprawnienia powinienem zastosować do udostępnionego woluminu na hoście?

Mogę wymyślić dwie opcje:

  • Do tej pory dałem wszystkim dostęp do odczytu / zapisu, dzięki czemu mogę pisać do folderu z kontenera Docker.

  • Mapuj użytkowników z hosta do kontenera, aby móc przypisać bardziej szczegółowe uprawnienia. Nie jestem pewien, czy jest to możliwe i nie znalazłem wiele na ten temat. Do tej pory wszystko, co mogę zrobić, to uruchomić kontener jako użytkownik: docker run -i -t -user="myuser" postgresale ten użytkownik ma inny identyfikator UID niż mój host myuser, więc uprawnienia nie działają. Nie jestem również pewien, czy mapowanie użytkowników będzie stanowić pewne zagrożenie bezpieczeństwa.

Czy są inne alternatywy?

Jak radzicie sobie z tym problemem?

Xabs
źródło
Sprawdź tę odpowiedź z podobnego pytania .
Batandwa,
1
Być może zainteresuje Cię także ten wątek, który szczegółowo omawia ten temat: groups.google.com/forum/#!msg/docker-user/cVov44ZFg_c/…
btiernay
W tej chwili zespół Docker nie planuje wdrożyć natywnego rozwiązania do montowania katalogów hosta jako woluminu o określonym identyfikatorze uid / gid. Zobacz mój komentarz i odpowiedzi na ten temat: github.com/docker/docker/issues/7198#issuecomment-230636074
Quinn Comendant

Odpowiedzi:

168

AKTUALIZACJA 2016-03-02 : Od Docker 1.9.0 Docker nazwał woluminy, które zastępują kontenery tylko do danych . Poniższa odpowiedź, podobnie jak mój link do posta na blogu, wciąż ma wartość w sensie myślenia o danych w oknie dokowanym, ale rozważ użycie nazwanych woluminów w celu zaimplementowania wzoru opisanego poniżej zamiast kontenerów danych.


Uważam, że kanonicznym sposobem rozwiązania tego jest użycie kontenerów zawierających tylko dane . Przy takim podejściu cały dostęp do danych woluminu odbywa się za pośrednictwem kontenerów korzystających -volumes-fromz kontenera danych, więc identyfikator użytkownika / identyfikator hosta nie ma znaczenia.

Na przykład jednym z przypadków użycia podanych w dokumentacji jest utworzenie kopii zapasowej woluminu danych. Aby to zrobić, inny kontener służy do tworzenia kopii zapasowej za pośrednictwem tar, a także używa go -volumes-fromdo zamontowania woluminu. Myślę więc, że kluczową kwestią dla grok jest: zamiast myśleć o tym, jak uzyskać dostęp do danych na hoście z odpowiednimi uprawnieniami, pomyśl o tym, jak zrobić to, czego potrzebujesz - kopie zapasowe, przeglądanie itp. - za pośrednictwem innego kontenera . Same kontenery muszą używać spójnego identyfikatora UID / GID, ale nie muszą mapować niczego na hoście, dzięki czemu pozostają przenośne.

Jest to również stosunkowo nowe dla mnie, ale jeśli masz konkretny przypadek użycia, możesz skomentować, a ja postaram się rozwinąć odpowiedź.

AKTUALIZACJA : Dla danego przypadku użycia w komentarzach możesz mieć obraz some/graphitedo uruchomienia grafitu i obraz some/graphitedatajako kontener danych. Ignorując porty i tym podobne, Dockerfileobraz some/graphitedatawygląda tak:

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"]

Zbuduj i utwórz kontener danych:

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

Plik some/graphiteDocker powinien mieć również ten sam identyfikator UID / GID, dlatego może wyglądać mniej więcej tak:

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"]

I byłby uruchamiany w następujący sposób:

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

Ok, teraz daje nam to nasz kontener grafitowy i powiązany pojemnik tylko z danymi z odpowiednim użytkownikiem / grupą (pamiętaj, że możesz również użyć some/graphitekontenera dla kontenera danych, zastępując entrypoing / cmd podczas jego uruchamiania, ale mając je jako oddzielne obrazy IMO jest wyraźniejsze).

Powiedzmy, że chcesz edytować coś w folderze danych. Zamiast montować wolumin na hoście i edytować go tam, utwórz nowy kontener, aby wykonać to zadanie. Nazwijmy to some/graphitetools. Utwórzmy także odpowiedniego użytkownika / grupę, podobnie jak some/graphiteobraz.

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"]

Możesz zrobić ten OSUSZANIE, dziedzicząc z some/graphitelub some/graphitedataw Dockerfile, lub zamiast tworzyć nowy obraz, po prostu ponownie użyj jednego z istniejących (w razie potrzeby zastępując punkt wejścia / cmd).

Teraz wystarczy uruchomić:

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

i potem vi /data/graphite/whatever.txt. Działa to doskonale, ponieważ wszystkie pojemniki mają tego samego użytkownika grafitowego z pasującym identyfikatorem uid / gid.

Ponieważ nigdy nie montujesz /data/graphitez hosta, nie obchodzi cię, w jaki sposób identyfikator uid / gid hosta mapuje się na identyfikator uid / gid zdefiniowany w kontenerach graphitei graphitetools. Kontenery te można teraz wdrożyć na dowolnym hoście i nadal będą działać idealnie.

Ciekawą rzeczą jest to, że graphitetoolsmoże mieć wiele przydatnych narzędzi i skryptów, które można teraz wdrażać w przenośny sposób.

AKTUALIZACJA 2 : Po napisaniu tej odpowiedzi postanowiłem napisać pełniejszy post na blogu o tym podejściu. Mam nadzieję, że to pomoże.

AKTUALIZACJA 3 : Poprawiłem tę odpowiedź i dodałem więcej szczegółów. Poprzednio zawierał on niepoprawne założenia dotyczące własności i perms - własność jest zwykle przypisywana w czasie tworzenia woluminu, tj. W kontenerze danych, ponieważ wtedy powstaje wolumin. Zobacz tego bloga . Nie jest to jednak wymagane - możesz po prostu użyć kontenera danych jako „referencji / uchwytu” i ustawić własność / perms w innym kontenerze poprzez chown w punkcie wejścia, który kończy się na gosu, aby uruchomić polecenie jako poprawny użytkownik. Jeśli ktoś jest zainteresowany tym podejściem, proszę o komentarz, a ja mogę podać linki do próbki przy użyciu tego podejścia.

Raman
źródło
35
Obawiam się, że to nie jest rozwiązanie, ponieważ będziesz miał ten sam problem z kontenerami tylko danych. Pod koniec dnia kontenery będą korzystać z woluminów udostępnionych z hosta, więc nadal będziesz musiał zarządzać uprawnieniami do tych folderów udostępnionych.
Xabs
2
Pamiętaj, że może być konieczne edytowanie folderu danych z mojego hosta (np. Usunięcie testowego klucza grafitowego, usunięcie mojego testowego folderu domowego JIRA lub zaktualizowanie go o najnowszą produkcyjną kopię zapasową ...). O ile rozumiem z twojego komentarza, powinienem robić rzeczy takie jak aktualizowanie danych JIRA za pośrednictwem trzeciego kontenera. W każdym razie, jakie uprawnienia zastosowałbyś do nowego folderu danych /data/newcontainer? Zakładam, że działasz dockerjako root (czy to możliwe, aby tego nie robić?) Czy istnieje jakakolwiek różnica w tych uprawnieniach, jeśli dane są montowane bezpośrednio w głównym kontenerze lub za pośrednictwem kontenera zawierającego tylko dane ?
Xabs,
2
Dziękuję za twoją wyszukaną odpowiedź. Przetestuję to, jak tylko będę miał szansę. Również miłe odniesienia zarówno do twojego posta na blogu, jak i do tego, jak używać minimalnych obrazów do kontenerów danych .
Xabs
3
Jedynym problemem związanym z tym podejściem jest bardzo łatwe pomyłkowe usunięcie kontenera. Wyobraź sobie, że to twój kontener danych. Myślę, że (CMIIW) dane nadal /var/lib/dockergdzieś będą, ale wciąż ogromny ból
lolski
3
„możesz po prostu użyć kontenera danych jako„ referencji / uchwytu ”i ustawić własność / perms w innym kontenerze poprzez chown w punkcie wejścia” ... @Raman: To jest sekcja, która w końcu mnie uratowała po wielu problemach z uprawnieniami pojąć. Korzystanie ze skryptu punktu wejścia i ustawianie uprawnień w tym działa dla mnie. Dziękuję za twoje szczegółowe wyjaśnienie. To najlepsze, jakie znalazłem do tej pory w sieci.
Vanderstaaij
59

Bardzo eleganckie rozwiązanie można zobaczyć na oficjalnym obrazie redis i ogólnie na wszystkich oficjalnych obrazach.

Opisane w procesie krok po kroku:

  • Utwórz użytkownika / grupę redis przed czymkolwiek innym

Jak widać na komentarzach Dockerfile:

dodaj najpierw naszego użytkownika i grupę, aby upewnić się, że ich identyfikatory zostaną przypisane konsekwentnie, niezależnie od dodanych zależności

  • Zainstaluj gosu z Dockerfile

gosu jest alternatywą su/ sudodla łatwego opuszczania konta przez użytkownika root. (Redis jest zawsze uruchamiany z redisużytkownikiem)

  • Skonfiguruj /datawolumin i ustaw go jako katalog roboczy

Po skonfigurowaniu woluminu / data za pomocą VOLUME /datapolecenia mamy teraz osobny wolumin, który może być woluminem dokującym lub montowanym na powiązaniu z katalogiem hosta.

Skonfigurowanie go jako workdir ( WORKDIR /data) powoduje, że jest to domyślny katalog, z którego wykonywane są polecenia.

  • Dodaj plik punktu dokowania i ustaw go jako ENTRYPOINT z domyślnym serwerem redis CMD

Oznacza to, że wszystkie wykonania kontenera będą uruchamiane przez skrypt dokera-punktu wejścia, a domyślnie polecenie do uruchomienia to serwer redis.

docker-entrypointJest to skrypt, który ma prostą funkcję: Zmiana własności bieżącego katalogu (/ data) i step-down z rootaby redisużytkownik mógł uruchomić redis-server. (Jeśli wykonane polecenie nie jest serwerem redis, uruchomi je bezpośrednio.)

Ma to następujący efekt

Jeśli katalog / data zostanie podłączony do hosta, punkt wejścia dokera przygotuje uprawnienia użytkownika przed uruchomieniem serwera redis w ramach redisużytkownika.

Zapewnia to spokój ducha, że ​​konfiguracja zerowa umożliwia uruchomienie kontenera w dowolnej konfiguracji woluminu.

Oczywiście, jeśli chcesz udostępnić głośność między różnymi obrazami, musisz upewnić się, że używają tego samego identyfikatora użytkownika / groupid, w przeciwnym razie najnowszy kontener przejmie uprawnienia użytkownika z poprzedniego.

Dimitris
źródło
11
Przyjęta odpowiedź ma charakter informacyjny, ale doprowadziła mnie tylko do tygodniowej frustracji z uprawnieniami do znalezienia tej odpowiedzi, która faktycznie stanowi kanoniczny sposób rozwiązania problemu.
m0meni
3
Bardzo dobrze wyjaśnione również tutaj: denibertovic.com/posts/handling-permissions-with-docker-volumes
kheraud
Więc? Jak sprawić, by objętość była zapisywalna z poziomu okna dokowanego? chownto w ENTRYPOINTskrypcie?
Gherman
34

Prawdopodobnie nie jest to najlepszy sposób w większości przypadków, ale nie został jeszcze wspomniany, więc być może pomoże komuś.

  1. Bindowanie woluminu hosta

    Host folder FOOBAR is mounted in container /volume/FOOBAR

  2. Zmodyfikuj skrypt startowy kontenera, aby znaleźć GID woluminu, który Cię interesuje

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

  3. Upewnij się, że użytkownik należy do grupy o tym identyfikatorze GID (może być konieczne utworzenie nowej grupy). W tym przykładzie będę udawać, że moje oprogramowanie działa jako nobodyużytkownik w kontenerze, więc chcę się upewnić, że nobodynależy do grupy o identyfikatorze grupy równymTARGET_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

Podoba mi się to, ponieważ mogę łatwo modyfikować uprawnienia grupowe na woluminach hosta i wiem, że te zaktualizowane uprawnienia obowiązują w kontenerze dokera. Dzieje się tak bez żadnych pozwoleń lub modyfikacji własności moich folderów / plików hosta, co mnie cieszy.

Nie podoba mi się to, ponieważ zakłada, że ​​nie ma niebezpieczeństwa w dodawaniu się do dowolnych grup w kontenerze, które akurat używają żądanego GID. Nie można go używać z USERklauzulą ​​w pliku Docker (chyba że ten użytkownik ma uprawnienia roota, jak sądzę). Poza tym krzyczy hackowanie ;-)

Jeśli chcesz być hardkorowy, możesz oczywiście rozszerzyć to na wiele sposobów - np. Wyszukaj wszystkie grupy w dowolnych podplikach, wielu woluminach itp.

Hamy
źródło
4
Czy jest to ukierunkowane na odczyt plików z zamontowanego woluminu? Szukam rozwiązania do pisania plików bez ich posiadania przez innego użytkownika niż ten, który utworzył kontener dokerów.
ThorSummoner,
Używam tego podejścia od 15 sierpnia. Wszystko było dobrze. Tylko uprawnienia do plików utworzonych w kontenerze były różne. Zarówno użytkownicy (wewnątrz i na zewnątrz kontenera) mają własność swoich plików, ale obaj mieli do nich dostęp do odczytu, ponieważ należeli do tej samej grupy utworzonej przez to rozwiązanie. Problem zaczął się, gdy przypadek użycia narzucił dostęp do zapisu do wspólnych plików. Większy problem polegał na tym, że udostępniony wolumin miał pliki git (jest to wolumin do testowania plików źródłowych deweloperów w tym samym kontekście produkcyjnym). Git zaczął ostrzegać o problemach z dostępem do udostępnionego kodu.
yumper
Myślę, że lepszym grepem $TARGET_GIDbyłoby użycie grep ':$TARGET_GID:', w przeciwnym razie, jeśli kontener ma np. Gid 10001, a twój host ma 1000, to sprawdzenie przejdzie, ale nie powinno.
robhudson,
16

Ok, teraz jest to śledzone w numerze dokera 7198

Na razie mam do czynienia z tą drugą opcją:

Zamapuj użytkowników z hosta w kontenerze

Plik Docker

#=======
# 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

AKTUALIZACJA Obecnie jestem bardziej skłonny do odpowiedzi Hamy'ego

Leo Gallucci
źródło
1
użyj polecenia id -u <username>, id -g <username>, id -G <username>aby uzyskać identyfikator użytkownika i identyfikator grupy użytkownika określonego zamiast
lolski
15
To niszczy przenośność kontenerów między hostami.
Raman
2
Problem Dockera nr 7198 doszedł do wniosku, że nie będą wdrażać natywnego rozwiązania w tym zakresie. Zobacz mój komentarz odpowiedzi na github.com/docker/docker/issues/7198#issuecomment-230636074
Quinn Comendant
12

Tak samo jak Ty, szukałem sposobu mapowania użytkowników / grup z hosta na kontenery dokujące i jest to najkrótszy sposób, jaki do tej pory znalazłem:

  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
        .....

To jest wyciąg z mojego docker-compose.yml.

Chodzi o to, aby montować (w trybie tylko do odczytu) listy użytkowników / grup z hosta do kontenera, więc po uruchomieniu kontenera będzie on miał takie same parametry uid-> nazwa użytkownika (jak również dla grup) z hostem. Teraz możesz skonfigurować ustawienia użytkownika / grupy dla usługi w kontenerze, tak jakby działała w systemie hosta.

Gdy zdecydujesz się przenieść kontener na inny host, wystarczy zmienić nazwę użytkownika w pliku konfiguracyjnym usługi na to, co masz na tym hoście.

Alex Myznikov
źródło
To świetna odpowiedź, bardzo prosta, jeśli chcesz uruchamiać kontenery, które obsługują pliki w systemie podstawowym, bez narażania reszty systemu.
icarito,
To moja ulubiona odpowiedź. Widziałem też podobną rekomendację w innym miejscu z komendą docker run, w której przekazujesz swoją bieżącą nazwę użytkownika / grupy -u $( id -u $USER ):$( id -g $USER )i nie musisz się już martwić o nazwę użytkownika. Działa to dobrze w lokalnych środowiskach programistycznych, w których chcesz generować pliki (na przykład pliki binarne), do których domyślnie masz dostęp do odczytu / zapisu.
matthewcummings516
5

Oto podejście, które nadal korzysta z kontenera tylko danych, ale nie wymaga jego synchronizacji z kontenerem aplikacji (pod względem posiadania tego samego identyfikatora UID / GID).

Przypuszczalnie chcesz uruchomić jakąś aplikację w kontenerze jako użytkownik inny niż root $ USER bez powłoki logowania.

W Dockerfile:

RUN useradd -s /bin/false myuser

# Set environment variables
ENV VOLUME_ROOT /data
ENV USER myuser

...

ENTRYPOINT ["./entrypoint.sh"]

Następnie w entrypoint.sh:

chown -R $USER:$USER $VOLUME_ROOT
su -s /bin/bash - $USER -c "cd $repo/build; $@"
Ethan
źródło
5

Aby zabezpieczyć i zmienić root dla kontenera dokowanego, host dokera spróbuj użyć --uidmapi --private-uidsopcji

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

Możesz również usunąć kilka możliwości ( --cap-drop) w kontenerze dokera dla bezpieczeństwa

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

Wsparcie UPDATE powinno wejśćdocker > 1.7.0

AKTUALIZACJA Wersja 1.10.0(2016-02-04) dodaj --userns-remapflagę https://github.com/docker/docker/blob/master/CHANGELOG.md#security-2

umount
źródło
Używam dokera 1.3.2 build 39fa2fa (najnowszy) i nie widzę śladów --uidmapani --private-uidsopcji. Wygląda na to, że PR nie udało się i nie został scalony.
Leo Gallucci
Nie łączy się w rdzeniu, jeśli chcesz, możesz użyć go jako łatki. Teraz możliwe jest tylko ograniczenie niektórych możliwości i uruchomienie aplikacji w kontenerze od użytkownika innego niż root.
umount
Czerwiec 2015 r. I nie widzę połączenia tego w oknie dokowanym 1.6.2. Czy Twoja odpowiedź jest nadal ważna?
Leo Gallucci
1
Problem nadal otwarty. Deweloper powinien dodać wsparcie w wersji 1.7. ( --root
umount
2
Wygląda na to, że programiści po raz kolejny przenieśli wydanie z tą funkcjonalnością. Twórca Dockera „icecrime” mówi "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 Więc myślę, że powinniśmy poczekać na następną stabilną wersję.
umount
4

Moje podejście polega na wykryciu bieżącego identyfikatora UID / GID, a następnie utworzenie takiego użytkownika / grupy w kontenerze i wykonanie skryptu pod nim. W rezultacie wszystkie pliki, które utworzy, będą pasować do użytkownika na hoście (którym jest skrypt):

# 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"
muni764
źródło
3

Obraz podstawowy

Użyj tego obrazu: https://hub.docker.com/r/reduardo7/docker-host-user

lub

Ważne: niszczy to przenośność kontenerów między hostami .

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) Buduj z docker

4) Uruchom!

sh run.sh
Eduardo Cuomo
źródło
0

W moim konkretnym przypadku próbowałem zbudować pakiet węzła z obrazem dokera węzła, aby nie musiałem instalować npm na serwerze wdrażania. Działało dobrze, dopóki poza kontenerem i na maszynie hosta nie próbowałem przenieść pliku do katalogu node_modules, który utworzył obraz dokera węzła, do którego odmówiono mi uprawnień, ponieważ był własnością root. Zdałem sobie sprawę, że mogę to obejść, kopiując katalog z kontenera na maszynę hosta. Za pomocą dokerów ...

Pliki skopiowane na komputer lokalny są tworzone za pomocą identyfikatora UID: GID użytkownika, który wywołał komendę docker cp.

To jest kod bashowy, którego użyłem do zmiany własności katalogu utworzonego przez i wewnątrz kontenera dokowanego.

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

W razie potrzeby możesz usunąć katalog za pomocą drugiego kontenera dokera.

docker run -v $(pwd)/build:/build -w="/build" --name $RMR_IMAGE node:6-slim rm -r node_modules
Johnklawlor
źródło
0

Aby udostępnić folder między hostem dokera a kontenerem dokowania, spróbuj wykonać poniższe polecenie

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

Flaga -v montuje bieżący katalog roboczy w kontenerze. Gdy katalog hosta woluminu podłączonego nie istnieje, Docker automatycznie utworzy ten katalog na hoście,

Mamy jednak 2 problemy:

  1. Nie możesz zapisywać na podłączonym woluminie, jeśli nie jesteś użytkownikiem root, ponieważ udostępniony plik będzie własnością innego użytkownika na hoście,
  2. Nie powinieneś uruchamiać procesu w kontenerach jako root, ale nawet jeśli uruchamiasz jako użytkownik zakodowany na stałe, nadal nie będzie pasował do użytkownika na twoim laptopie / Jenkinsie,

Rozwiązanie:

Kontener: utwórz użytkownika o nazwie „testser”, domyślnie identyfikator użytkownika zaczyna się od 1000,

Host: utwórz grupę, powiedz „grupa testowa” o identyfikatorze grupy 1000, i prześlij katalog do nowej grupy (grupa testowa

Praveen Muthusamy
źródło
-5

Jeśli używasz Docker Compose, uruchom kontener w trybie uprzywilejowanym:

wordpress:
    image: wordpress:4.5.3
    restart: always
    ports:
      - 8084:80
    privileged: true
Renato Alencar
źródło
2
Może to ułatwić montowanie woluminów, ale .. Wordpress uruchomiony w trybie uprzywilejowanym? To okropny pomysł, który wymaga kompromisu. wpvulndb.com/wordpresses/453
Colin Harrington