Apa cara (terbaik) untuk mengelola izin untuk volume bersama Docker?

345

Saya telah bermain-main dengan Docker untuk sementara waktu dan terus menemukan masalah yang sama ketika berhadapan dengan data persisten.

Saya membuat Dockerfiledan memaparkan volume atau gunakan --volumes-fromuntuk memasang folder host di dalam wadah saya .

Izin apa yang harus saya terapkan pada volume bersama di host?

Saya dapat memikirkan dua opsi:

  • Sejauh ini saya sudah memberi semua orang akses baca / tulis, jadi saya bisa menulis ke folder dari wadah Docker.

  • Petakan pengguna dari host ke dalam wadah, sehingga saya dapat menetapkan lebih banyak izin granular. Tidak yakin ini mungkin terjadi dan belum menemukan banyak tentang itu. Sejauh ini, yang bisa saya lakukan adalah menjalankan container sebagai beberapa pengguna:, docker run -i -t -user="myuser" postgrestetapi pengguna ini memiliki UID yang berbeda dari host saya myuser, jadi izin tidak berfungsi. Juga, saya tidak yakin jika memetakan pengguna akan menimbulkan risiko keamanan.

Apakah ada alternatif lain?

Bagaimana kalian menangani masalah ini?

Xab
sumber
Lihat jawaban ini dari pertanyaan serupa .
Batandwa
1
Anda mungkin juga tertarik dengan utas ini yang membahas topik ini secara terperinci: groups.google.com/forum/#!msg/docker-user/cVov44ZFg_c/…
btiernay
Saat ini, tim Docker tidak berencana untuk mengimplementasikan solusi asli untuk memasang direktori-host sebagai volume dengan uid / gid yang ditentukan. Lihat komentar saya dan balasan tentang masalah ini: github.com/docker/docker/issues/7198#issuecomment-230636074
Quinn Comendant

Jawaban:

168

UPDATE 2016-03-02 : Pada Docker 1.9.0, Docker telah menamai volume yang menggantikan wadah hanya-data . Jawaban di bawah ini, serta posting blog saya yang tertaut, masih memiliki nilai dalam arti bagaimana berpikir tentang data di dalam buruh pelabuhan tetapi mempertimbangkan menggunakan volume bernama untuk menerapkan pola yang dijelaskan di bawah daripada wadah data.


Saya percaya cara kanonik untuk menyelesaikan ini adalah dengan menggunakan wadah data saja . Dengan pendekatan ini, semua akses ke data volume adalah melalui wadah yang menggunakan -volumes-fromwadah data, sehingga host uid / gid tidak masalah.

Misalnya, satu use case yang diberikan dalam dokumentasi adalah membuat cadangan volume data. Untuk melakukan ini, wadah lain digunakan untuk melakukan pencadangan melalui tar, dan juga digunakan -volumes-fromuntuk memasang volume. Jadi saya pikir poin utama untuk grok adalah: daripada berpikir tentang cara mendapatkan akses ke data di host dengan izin yang tepat, pikirkan tentang bagaimana melakukan apa pun yang Anda butuhkan - backup, browsing, dll. - melalui wadah lain . Wadah itu sendiri harus menggunakan uid / gids yang konsisten, tetapi mereka tidak perlu memetakan apa pun di host, sehingga tetap portabel.

Ini relatif baru bagi saya juga, tetapi jika Anda memiliki kasus penggunaan tertentu jangan ragu untuk berkomentar dan saya akan mencoba untuk memperluas jawabannya.

PEMBARUAN : Untuk kasus penggunaan yang diberikan dalam komentar, Anda mungkin memiliki gambar some/graphiteuntuk menjalankan grafit, dan gambar some/graphitedatasebagai wadah data. Jadi, mengabaikan port dan semacamnya, Dockerfilegambarnya some/graphitedataadalah seperti:

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

Buat dan buat wadah data:

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

The some/graphiteDockerfile juga harus mendapatkan uid yang sama / Gids, oleh karena itu mungkin terlihat seperti ini:

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

Dan itu akan dijalankan sebagai berikut:

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

Oke, sekarang yang memberi kami wadah grafit dan wadah khusus data yang terkait dengan pengguna / grup yang benar (perhatikan bahwa Anda juga dapat menggunakan kembali some/graphitewadah tersebut untuk wadah data, mengesampingkan masukan / cmd saat menjalankannya, tetapi menjadikannya sebagai memisahkan gambar IMO lebih jelas).

Sekarang, katakanlah Anda ingin mengedit sesuatu di folder data. Jadi daripada mengikat pemasangan volume ke host dan mengeditnya di sana, buat wadah baru untuk melakukan pekerjaan itu. Mari kita sebut saja some/graphitetools. Mari kita juga membuat pengguna / grup yang tepat, seperti some/graphitegambar.

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

Anda dapat membuat KERING ini dengan mewarisi dari some/graphiteatau some/graphitedatadi Dockerfile, atau alih-alih membuat gambar baru gunakan kembali salah satu yang sudah ada (menimpa entrypoint / cmd seperlunya).

Sekarang, Anda cukup menjalankan:

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

dan kemudian vi /data/graphite/whatever.txt. Ini berfungsi dengan baik karena semua kontainer memiliki pengguna grafit yang sama dengan uid / gid yang cocok.

Karena Anda tidak pernah me-mount /data/graphitedari host, Anda tidak peduli bagaimana host uid / gid memetakan ke uid / gid yang didefinisikan di dalam graphitedan graphitetoolskontainer. Kontainer tersebut sekarang dapat digunakan untuk host mana saja, dan mereka akan terus bekerja dengan sempurna.

Hal yang rapi tentang ini adalah bahwa graphitetoolsbisa memiliki semua jenis utilitas dan skrip yang bermanfaat, yang kini dapat Anda gunakan secara portabel.

UPDATE 2 : Setelah menulis jawaban ini, saya memutuskan untuk menulis posting blog yang lebih lengkap tentang pendekatan ini. Saya harap ini membantu.

UPDATE 3 : Saya memperbaiki jawaban ini dan menambahkan lebih spesifik. Sebelumnya berisi beberapa asumsi yang salah tentang kepemilikan dan perms - kepemilikan biasanya diberikan pada waktu pembuatan volume yaitu dalam wadah data, karena saat itulah volume dibuat. Lihat blog ini . Ini bukan persyaratan - Anda hanya dapat menggunakan wadah data sebagai "referensi / pegangan" dan mengatur kepemilikan / perms dalam wadah lain melalui chown di entri point, yang berakhir dengan gosu untuk menjalankan perintah sebagai pengguna yang benar. Jika ada yang tertarik dengan pendekatan ini, silakan komentar dan saya dapat memberikan tautan ke sampel menggunakan pendekatan ini.

Raman
sumber
35
Saya khawatir ini bukan solusi karena Anda akan memiliki masalah yang sama dengan wadah hanya data. Pada akhirnya, kontainer ini akan menggunakan volume yang dibagikan dari host, jadi Anda masih harus mengelola izin pada folder yang dibagikan itu.
Xabs
2
Ingatlah bahwa saya mungkin perlu mengedit folder data dari host saya (yaitu: hapus kunci tes grafit, hapus folder home test JIRA saya atau perbarui dengan cadangan produksi terbaru ...). Sejauh yang saya mengerti dari komentar Anda, saya harus melakukan hal-hal seperti memperbarui data JIRA melalui wadah ke-3. Dalam hal apa pun, izin apa yang akan Anda terapkan ke folder data baru /data/newcontainer? Saya berasumsi Anda menjalankan dockersebagai root (apakah mungkin untuk tidak melakukannya?) Juga, apakah ada perbedaan dalam izin tersebut jika data dipasang langsung di wadah utama atau melalui wadah data saja ?
Xabs
2
Terima kasih atas balasan terperinci Anda. Akan menguji ini segera setelah saya memiliki kesempatan. Juga, referensi yang bagus baik posting blog Anda dan yang tentang menggunakan gambar minimal untuk wadah data .
Xabs
3
Satu-satunya masalah dengan pendekatan ini adalah sangat mudah untuk menghapus suatu wadah secara tidak sengaja. Bayangkan jika itu adalah wadah data Anda. Saya pikir (CMIIW) data akan tetap di /var/lib/dockersuatu tempat tetapi masih sangat menyakitkan
lolski
3
"Anda bisa menggunakan wadah data sebagai" referensi / pegangan "dan mengatur kepemilikan / perms dalam wadah lain melalui chown di titik masuk" ... @Raman: Ini adalah bagian yang akhirnya menyelamatkan saya setelah memiliki banyak masalah izin tidak tahu. Menggunakan skrip entrypoint dan izin pengaturan dalam hal ini berfungsi untuk saya. Terima kasih atas penjelasan terperinci Anda. Ini adalah yang terbaik yang saya temukan di web sejauh ini.
Vanderstaaij
59

Solusi yang sangat elegan dapat dilihat pada gambar redis resmi dan secara umum di semua gambar resmi.

Dijelaskan dalam proses langkah demi langkah:

  • Buat redis pengguna / grup sebelum yang lain

Seperti yang terlihat di komentar Dockerfile:

tambahkan pengguna dan grup kami terlebih dahulu untuk memastikan ID mereka ditugaskan secara konsisten, terlepas dari apa pun dependensi yang ditambahkan

  • Instal gosu dengan Dockerfile

gosu adalah alternatif su/ sudountuk step-down yang mudah dari pengguna root. (Redis selalu dijalankan dengan redispengguna)

  • Konfigurasikan /datavolume dan atur sebagai workdir

Dengan mengkonfigurasi volume / data dengan VOLUME /dataperintah kita sekarang memiliki volume terpisah yang dapat berupa volume buruh pelabuhan atau bind-mount ke dir host.

Mengkonfigurasinya sebagai workdir ( WORKDIR /data) menjadikannya direktori default tempat perintah dijalankan.

  • Tambahkan file docker-entrypoint dan tetapkan sebagai ENTRYPOINT dengan redis-server CMD default

Ini berarti bahwa semua eksekusi kontainer akan dijalankan melalui skrip docker-entrypoint, dan secara default perintah yang akan dijalankan adalah redis-server.

docker-entrypointadalah skrip yang melakukan fungsi sederhana: Mengubah kepemilikan direktori saat ini (/ data) dan turun dari rootmenjadi redispengguna untuk menjalankan redis-server. (Jika perintah yang dijalankan bukan redis-server, itu akan menjalankan perintah secara langsung.)

Ini memiliki efek sebagai berikut

Jika direktori / data diikat-mount ke host, docker-entrypoint akan menyiapkan izin pengguna sebelum menjalankan redis-server di bawah redispengguna.

Ini memberi Anda kemudahan bahwa ada pengaturan nol untuk menjalankan wadah di bawah konfigurasi volume apa pun.

Tentu saja jika Anda perlu berbagi volume antara gambar yang berbeda, Anda perlu memastikan mereka menggunakan userid / groupid yang sama jika tidak, wadah terbaru akan membajak izin pengguna dari yang sebelumnya.

Dimitris
sumber
11
Jawaban yang diterima informatif, tetapi hanya membuat saya frustrasi selama seminggu dengan izin untuk menemukan jawaban ini yang sebenarnya menyediakan cara kanonik untuk menyelesaikan masalah.
m0meni
3
Dijelaskan dengan sangat baik juga di sini: denibertovic.com/posts/handling-permissions-with-docker-volumes
kheraud
Begitu? Bagaimana cara membuat volume dapat ditulis dari dalam docker? chownitu di dalam ENTRYPOINTskrip?
Gherman
34

Ini bisa dibilang bukan cara terbaik untuk sebagian besar keadaan, tetapi belum disebutkan jadi mungkin itu akan membantu seseorang.

  1. Bind mount volume host

    Host folder FOOBAR is mounted in container /volume/FOOBAR

  2. Ubah skrip startup kontener Anda untuk menemukan GID volume yang Anda minati

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

  3. Pastikan pengguna Anda milik grup dengan GID ini (Anda mungkin harus membuat grup baru). Untuk contoh ini saya akan berpura-pura perangkat lunak saya berjalan sebagai nobodypengguna ketika berada di dalam wadah, jadi saya ingin memastikan nobodymilik grup dengan id grup sama denganTARGET_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

Saya suka ini karena saya dapat dengan mudah mengubah izin grup pada volume host saya dan tahu bahwa izin yang diperbarui berlaku di dalam wadah buruh pelabuhan. Ini terjadi tanpa izin atau modifikasi kepemilikan pada folder / file host saya, yang membuat saya senang.

Saya tidak suka ini karena mengasumsikan tidak ada bahaya dalam menambahkan diri Anda ke grup sewenang-wenang di dalam wadah yang kebetulan menggunakan GID yang Anda inginkan. Itu tidak dapat digunakan dengan USERklausa di Dockerfile (kecuali jika pengguna itu memiliki hak root). Juga, ia menjerit pekerjaan hack ;-)

Jika Anda ingin menjadi hardcore, Anda dapat dengan jelas memperluas ini dengan banyak cara - mis. Mencari semua grup di subfil, banyak volume, dll.

Hamy
sumber
4
Apakah ini ditargetkan untuk membaca file dari volume yang dipasang? Saya mencari solusi untuk menulis file tanpa dimiliki oleh pengguna lain daripada mereka yang membuat wadah buruh pelabuhan.
ThorSummoner
Saya menggunakan pendekatan ini sejak 15 Agustus. Semuanya baik-baik saja. Hanya izin dari file yang dibuat di dalam wadah itu berbeda. Keduanya, pengguna (di dalam dan di luar wadah) memiliki kepemilikan file mereka tetapi keduanya telah membaca mengaksesnya karena mereka memang milik kelompok yang sama yang dibuat oleh solusi ini. Masalahnya dimulai ketika use case memaksakan akses tulis ke file umum. Masalah yang lebih besar adalah bahwa volume bersama memiliki file git (ini adalah volume untuk menguji file sumber dev dalam konteks produksi yang sama). Git mulai memperingatkan tentang masalah akses ke kode bersama.
Yucer
Saya pikir grep yang lebih baik $TARGET_GIDadalah menggunakan grep ':$TARGET_GID:', jika tidak, jika wadahnya memiliki, misalnya gid 10001 dan host Anda adalah 1000, cek ini akan berlalu tetapi seharusnya tidak.
robhudson
16

Ok, ini sekarang sedang dilacak pada masalah buruh pelabuhan # 7198

Untuk saat ini, saya berurusan dengan ini menggunakan opsi kedua Anda:

Petakan pengguna dari host ke dalam wadah

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

PEMBARUAN Saya saat ini lebih condong ke jawaban Hamy

Leo Gallucci
sumber
1
menggunakan perintah id -u <username>, id -g <username>, id -G <username>untuk mendapatkan user id dan kelompok id dari pengguna tertentu bukannya
lolski
15
Ini menghancurkan portabilitas kontainer di seluruh host.
Raman
2
Masalah Docker # 7198 sampai pada kesimpulan mereka tidak akan mengimplementasikan solusi asli untuk ini. Lihat komentar saya, balasan di github.com/docker/docker/issues/7198#issuecomment-230636074
Quinn Comendant
12

Sama seperti Anda, saya sedang mencari cara untuk memetakan pengguna / grup dari host ke kontainer buruh pelabuhan dan ini adalah cara terpendek yang saya temukan sejauh ini:

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

Ini adalah ekstrak dari docker-compose.yml saya.

Idenya adalah untuk me-mount (dalam mode read-only) daftar pengguna / grup dari host ke container sehingga setelah kontainer dijalankan akan memiliki nama pengguna> username (dan juga grup) yang sama dengan host. Sekarang Anda dapat mengonfigurasi pengaturan pengguna / grup untuk layanan Anda di dalam wadah seolah-olah itu berfungsi pada sistem host Anda.

Ketika Anda memutuskan untuk memindahkan wadah Anda ke host lain, Anda hanya perlu mengubah nama pengguna di file konfigurasi layanan ke apa yang Anda miliki di host itu.

Alex Myznikov
sumber
Ini adalah jawaban yang bagus, sangat sederhana jika Anda ingin menjalankan wadah yang menangani file pada sistem dasar, tanpa mengekspos sisa sistem.
icarito
Ini jawaban favorit saya. Juga, saya melihat rekomendasi serupa di tempat lain dengan perintah menjalankan buruh pelabuhan di mana Anda mengirimkan nama pengguna / grup saat ini melalui -u $( id -u $USER ):$( id -g $USER )dan Anda tidak perlu lagi khawatir tentang nama pengguna. Ini bekerja dengan baik untuk lingkungan dev lokal di mana Anda ingin menghasilkan file (misalnya binari) yang telah Anda akses akses baca / tulis secara default.
matthewcummings516
5

Berikut adalah pendekatan yang masih menggunakan wadah data saja tetapi tidak mengharuskannya untuk disinkronkan dengan wadah aplikasi (dalam hal memiliki uid / gid yang sama).

Agaknya, Anda ingin menjalankan beberapa aplikasi dalam wadah sebagai $ USER non-root tanpa shell login.

Di Dockerfile:

RUN useradd -s /bin/false myuser

# Set environment variables
ENV VOLUME_ROOT /data
ENV USER myuser

...

ENTRYPOINT ["./entrypoint.sh"]

Lalu, di entrypoint.sh:

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

Untuk mengamankan dan mengubah root untuk wadah buruh pelabuhan tuan rumah buruh pelabuhan coba gunakan --uidmapdan --private-uidsopsi

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

Anda juga dapat menghapus beberapa kemampuan ( --cap-drop) dalam wadah buruh pelabuhan untuk keamanan

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

Dukungan UPDATE harus masukdocker > 1.7.0

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

umount
sumber
Saya menjalankan buruh pelabuhan 1.3.2 build 39fa2fa (terbaru) dan tidak melihat jejak opsi --uidmapmaupun --private-uids. Sepertinya PR tidak berhasil dan tidak digabung.
Leo Gallucci
Itu tidak bergabung dalam inti, jika Anda mau, Anda bisa menggunakannya bagaimana patch. Sekarang hanya mungkin membatasi beberapa kemampuan dan menjalankan aplikasi Anda dalam wadah dari pengguna non root.
umount
Juni 2015 dan saya tidak melihat ini digabungkan dalam docker 1.6.2 apakah jawaban Anda masih valid?
Leo Gallucci
1
Masalah masih terbuka. Pengembang harus menambahkan dukungan dalam versi 1.7. (--root option) github.com/docker/docker/pull/12648
umount
2
Tampaknya para pengembang sekali lagi memindahkan rilis dengan fungsi ini. Pengembang Docker "icecrime" mengatakan "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 Jadi saya pikir kita harus menunggu versi stabil berikutnya.
umount
4

Pendekatan saya adalah mendeteksi UID / GID saat ini, kemudian membuat pengguna / grup di dalam wadah dan menjalankan skrip di bawahnya. Akibatnya semua file yang akan dibuat akan cocok dengan pengguna di host (yang merupakan skrip):

# 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
sumber
3

Gambar Dasar

Gunakan gambar ini: https://hub.docker.com/r/reduardo7/docker-host-user

atau

Penting: ini menghancurkan portabilitas kontainer di seluruh host .

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) Bangun dengan docker

4) Lari!

sh run.sh
Eduardo Cuomo
sumber
0

Dalam kasus khusus saya, saya mencoba untuk membangun paket node saya dengan gambar docker simpul sehingga saya tidak perlu menginstal npm di server penyebaran. Ini bekerja dengan baik sampai, di luar wadah dan pada mesin host, saya mencoba untuk memindahkan file ke direktori node_modules yang telah dibuat gambar docker node, yang saya ditolak izinnya karena dimiliki oleh root. Saya menyadari bahwa saya dapat mengatasi ini dengan menyalin direktori keluar dari wadah ke mesin host. Melalui dok buruh pelabuhan ...

File yang disalin ke mesin lokal dibuat dengan UID: GID dari pengguna yang memanggil perintah docker cp.

Ini adalah kode bash yang saya gunakan untuk mengubah kepemilikan direktori yang dibuat oleh dan di dalam wadah buruh pelabuhan.

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

Jika perlu, Anda dapat menghapus direktori dengan wadah buruh pelabuhan kedua.

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

Untuk berbagi folder antara host buruh pelabuhan dan wadah buruh pelabuhan, coba perintah di bawah ini

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

Bendera -v memasang direktori kerja saat ini ke dalam wadah. Ketika direktori host volume bind-mount tidak ada, Docker akan secara otomatis membuat direktori ini pada host untuk Anda,

Namun, ada 2 masalah yang kita miliki di sini:

  1. Anda tidak dapat menulis ke volume yang dipasang jika Anda adalah pengguna non-root karena file yang dibagikan akan dimiliki oleh pengguna lain di host,
  2. Anda seharusnya tidak menjalankan proses di dalam wadah Anda sebagai root tetapi bahkan jika Anda menjalankan sebagai pengguna dengan kode keras, itu masih tidak akan cocok dengan pengguna di laptop Anda / Jenkins,

Larutan:

Wadah: buat pengguna mengatakan 'testuser', secara default id pengguna akan mulai dari 1000,

Host: buat grup katakan 'testgroup' dengan id grup 1000, dan beri tahu direktori ke grup baru (testgroup

Praveen Muthusamy
sumber
-5

Jika Anda menggunakan Docker Compose, mulai wadah dalam mode yang dicegah:

wordpress:
    image: wordpress:4.5.3
    restart: always
    ports:
      - 8084:80
    privileged: true
Renato Alencar
sumber
2
Ini mungkin membuatnya lebih mudah untuk me-mount volume tapi .. Wordpress diluncurkan dalam mode priviledge? Itu ide yang mengerikan - yaitu meminta untuk dikompromikan. wpvulndb.com/wordpresses/453
Colin Harrington