Moby: uidとgidを共有ボリューム用に構成可能にする

作成日 2014年07月23日  ·  141コメント  ·  ソース: moby/moby

共有ボリュームの所有権を構成可能にするオプションを提供してください。

たとえば、私の現在のユースケースは、/ var / lib / dockerがホストからのボリュームとして読み取り専用で共有されているコンテナ内でlogstash-forwarderを実行することです。

ホストで/ var / lib / dockerが0700root :rootに設定されているため、root以外のユーザーとしてボリュームにアクセスできません。

私が欲しいのは、ホストからクライアントのユーザーとグループにuidとgidをマップできるNFSのようなものです。

つまり、docker run -v / var / lib / docker:/ var / lib / docker:ro :$ user:$ groupは、$ user:$ groupに属する、読み取り専用としてコンテナー内でボリュームを使用できるようにします。

kinfeature

最も参考になるコメント

uid / gidをマッピングするには、クロスプラットフォームのgo-to(gosuではない)ソリューションが本当に必要です。 この問題だけでも、Dockerが初心者に認識される方法に大きな損害を与えます。

全てのコメント141件

彼らがこれをどのように実装したかはわかりません。Linuxに同等の機能が存在するが、OS Xには、ボリュームの「所有権を無視する」機能が存在します。 事実上、これにより、_any_ユーザーはファイル/ディレクトリを所有者であるかのように見ることができます。

これはすべての場合に役立つわけではありませんが、それは素晴らしい追加かもしれません

+1

関連: http

gh#5910は、SELinux側からこれを処理します。

リンク:#5910;)

SELinuxの変更は、実際にはコンテンツのラベルを変更しています。 潜在的に、ホスト上で変更を行うことができます。 UID / GIDに対してこれを行う他の方法を私は知りません。 ただし、マウントポイントでchown -R $ UID:$ GIDを実行します。

または、ACLを使用してこのタイプのアクセスを追加することもできます。 ただし、マウントポイントのすべてのINODEを変更する必要があると思います。

この機能も必要です。

たとえば、Webコンテナーを作成し、それにWebサイトと構成を含むボリュームをアタッチして、コンテナーが任意の数のWebサイトに対して完全にユニバーサルになるようにします。

ただし、コードをWebサイトリポジトリにプッシュするにはgitアクセスが必要です。 アプリを分離したいので、各Webサイトディレクトリを別々のユーザー/グループが所有するようにしたいので、Dockerコンテナーによってボリュームに書き込まれたファイルがその別々のユーザー/グループによって所有されると便利です。

この機能の+1。
読み取り/書き込みボリュームがそれなしでどのように機能するかを理解していません。 guid / uidがイメージとホストで同じであることを期待することは、Dockerの分離原則と互換性のない強い要件です。

私はDocker化された開発ツール用の醜くて遅いuseradd / groupaddコマンドでこれを個人的に回避しています: https

私は完全に要点を見逃しているかもしれません。 しかし、httpユーザーが/ var / logに対する書き込み権限を持っていることを確認したいという同様の問題に苦労していました。これはボリュームであり、所有者としてroot:rootを持つホストからのものである可能性があります。

ログディレクトリが作成され、適切なアクセス許可を持つことを保証するエントリポイントを設定することで、これを解決しました。 エントリポイントスクリプトがrootとして実行されるため、これは機能すると思います。

(コメントを削除しました-タブが間違っています、申し訳ありません)

Dockerの外部のUbuntuでこれをハッキングしました。 パッケージbindfsをインストールし、ボリュームの内容を含むディレクトリを別のパスにバインドし、UIDとGIDをコンテナ内で使用されるパスにマッピングします。

sudo bindfs -u UID -g GID oldpath newpath

次に、newpathをDockerボリュームとして使用します。 Oldpathは、ホストの所有権が正しいこと、ゲストの所有権がnewpathであることを示しています。

@jjv問題は、bindfsが本当に本当に遅いことです。

@ cpuguy83はい、それは最適にはほど遠いですが、おそらく同様の状況で誰かを助けます。 これは、本番環境でUIDとGIDがホストとゲストの間で一致している必要があるときに、開発仮想マシン内で動作させるためでした(vmhgfsではUID / GIDの設定は許可されていません)。

dockerがこれを実装するときに、ある種のbindfs機能が使用されていれば、パフォーマンスにあまり影響を与えないと仮定すると、実際には便利です。 そうすれば、コンテナが正しいユーザーとして実行されていることを確認する必要がなくなります。 リテラルのuid / gidの代わりに論理名を使用することも可能であるはずです。

@jsternbergこれは

+1

ローカル開発のユースケースでは、Dockerには間違いなくこの機能が必要だと思います。 そしてそのような場合、私はこの機能がWindowsとOSXの両方をサポートすることを望んでいます。

ただし、Vagrantは、ホストユーザーのUID / PIDをvagrantユーザーにマッピングすることでこれをサポートしているようです。 しかし、開発目的では、マルチホストアプリケーションを実行するのにVagrantよりもはるかに軽量であるため、Vagrantの代わりにDockerを使用したいと思います。

ここで欠けているものを教えてください(Goの経験はありません)が、Go Mount()関数はフラグを受け入れませんか? 次のようなコマンドを許可できませんでした
-v host/folder:container/folder -mount-as user:group
ルックアップでuid / gidを取得できませんでした(https://golang.org/src/os/user/lookup_unix.go)
次に、それら(uid = 1、gid = 1)をフラグとしてMount()に渡しますか? (https://golang.org/src/syscall/syscall_linux.go?s=19154:19249#L754)

@krisgrahamバインドマウントは、そのようなuid / gidの設定をサポートしていません。

また、-vオプションを--mount-asオプションから分離すると、複数の-vオプションがある場合に混乱が生じます。

これの良い回避策は何ですか? Dockerをアクティブな開発に使用したいのですが、コードを変更するたびに再構築する必要があるため、何らかのマウントされたボリュームがないことは実際にはオプションではありません。

Dockerをアクティブな開発に使用したい理由は、Dockerが本番環境と一貫性を保つためです。

@berfarah私は毎日活発な開発のために
パーマをいじる必要がある場合はめったにありません。
OSXでboot2dockerを使用している場合は、作業ディレクトリが/ Users内にあることを確認してください。問題はないはずです。

@ cpuguy83迅速な返信ありがとうございます。 ログを書き込めないRails環境でパーミッションの問題が発生し、パーミッションが原因で障害点が発生することがあります。 これは、私のサービスがファイルの1つとは異なるUIDを持っているためです。

@berfarah私の回避策は、コードを所有するcontainer-users / groupsがホストユーザーと同じUID / GUIDを持つようにdockerfilesを作成することです。 たとえば、ホストユーザーのUIDが1000であるため、次のようになります。

RUN \
    groupadd code_executor_group && \
    useradd code_executor_user -g code_executor_group -u 1000

@berfarah RAILS_ENV = developmentのstdout / stderrに移動するログがありますか?

@ cpuguy83この問題はOSXには影響しません。 thaJeztahは2014年7月24日にコメントしました:

OS Xには、ボリュームの「所有権を無視する」機能があります。 事実上、これにより、すべてのユーザーに、所有者であるかのようにファイル/ディレクトリが表示されます。

@ncjonesは、実際には、OS Xにも同じことが当てはまります。そこで話していた「ボリューム」は、OS X自体で使用されるハードディスク/パーティション(ボリューム)です。 それがBoot2Dockerでの作業に違いをもたらすとは思えませんが、よくわかりません。

私のコメントは、Linuxで(したがってBoot2Docker VM内で)何か_類似した_ことが可能かどうかを通知することを目的としていました。

混乱してすみません。

@ryneeverettありがとう、それは役に立ちます。 次に、必要に応じて、アクセス許可を755から775に、644から664にそれぞれ変更することになりますか? 編集:読書スキル!

@ cpuguy83ありがとう! これは、 @ ryneeverettのソリューションよりも制限的な修正のように思われます。これは、すべてのプロジェクトに

@berfarahお役に立ててうれしいです。 ええ、ホストファイルに正しい権限があり、Dockerがそれらをボリュームに保持していることを確認するだけです。

+1

これは、Dockerを介した共有ボリュームに非常に役立つものであり、私が抱えているセキュリティ上の懸念に対処します。

  • コンテナーuidおよびgidが誤ってホスト上の特権のある非rootユーザーにマップされる共有ボリューム。 (例:ホスト上のコンテナーによって作成されたファイルは、passwdなしでsudoを実行したり、制限されたコンテンツにアクセスしたりできるユーザーにマッピングされています。)

これを修正することは、Apacheまたはいくつかのミドルウェアを使用して大量のコンテナを実行し、ロギングボリュームやさまざまなコンテンツ/アップロードディレクトリを共有する企業にとって非常に便利です。 また、Linuxでエンドユーザーアプリ(syncomm / spotifyなど)をコンテナー化する際に、これらのアクセス許可に関して個人的に頭痛の種がありました。 今日の回避策の多くは、それ自体が問題です。 最終的に、これはdocker内で修正する必要があります。 特に、この問題がコンテナ内の0:0 uid / gidがホストのrootにどのようにマップされるかを浮き彫りにする場合は特に、rootシェルスクリプトをエントリポイントとして実行することに抵抗があります。 私は最初の提案「dockerrun-v / var / lib / docker:/ var / lib / docker:ro :$ user:$ group」が好きです。

@syncomm私は正反対のアプローチを取ります。
Dockerは、データの所有権について推測することはできません。

コメントの下部で強調表示するアプローチは、これらの実際のファイルを、uid / gidを変更できるヒューズベースのfsに自動的にマッピングする場合に実行可能であり、パフォーマンスに大きな影響を与えます。

そしてすぐに、コンテナ内のuid0はホスト上のuid0になりません...これにより、ファイルの所有権もさらに複雑になります。

これは#2259の複製ですか?

@ cpuguy83フィードバックをありがとうございますが、正反対のアプローチが何を意味するのか

bindfsの回避策と同様に、それをヒューズラッパーにすると、かなりのオーバーヘッドが発生することに同意します。 しかし、大きなペナルティなしにこの難問から抜け出す方法がなければなりません。 基本的に、コンテナは正しく動作しており(ホストとは別の一意のマシンであるかのように)、ホストのディレクトリをボリュームとしてマウントすると、POSIXファイルシステム、アクセス許可などが(正しく)表示されます。 残念ながら、そのため、2つの「ホスト」間で一貫した方法でデータを共有することは非常に困難です。 nfs、cifsなどがこれに使用され、uidとgidのマッピングをサポートします。問題の解決には類似点があると思います。 正直なところ、これがコードのどこで起こっているのかを理解し、それをよりよく理解するために、リポジトリをさらに掘り下げる必要があります。

ファイルの所有権について言及した変更はいつ削除されますか? uid 0がコンテナとホストで同じではない場合、実際には、ルートシェルスクリプトのエントリポイントを作成する方がはるかに快適です。 次に、正しいuid / gidをenvとして渡し、コンテナーの起動時にadduserを実行するという推奨される回避策を実行するだけです。

@syncomm残念ながら、私の知識ではありません

最終的に、これはUIDとGIDの完全な双方向再マッピングのためのカーネルサポートを必要とするもののように見え、管理も簡単ではないように見えます。

パフォーマンスに敏感でないシナリオでは、FUSEを使用して何かを行うことができます。

家にルート所有のファイルができてしまうので、開発のユースケースではまだ+1です。

私のユースケースでは、Dockerが作成時にカスタムuid / gidとselinuxラベルをホストボリュームに適用し、ディレクトリがすでに存在する場合はアクセス許可とラベルをそのままにしておけば十分です。 現在、ボリュームのアクセス許可を修正するためだけにルートとして実行されるイメージのエントリポイントを分離することで、この問題を回避しています。

@ibukanov uid / gidを適用できませんが、selinuxラベルが登場します。

@ cpuguy83ホストボリュームディレクトリを作成するときにカスタムuid / gidを適用できない技術的な理由は何ですか?

@ibukanov上記のコメントを参照してください。

@ cpuguy83コメントから問題が何であるかわかりません。 私のユーザーの場合、uid / gidを再マッピングする必要はありません。 ルートとして実行しているとき、現在コンテナ内でchown uid:gid /host_volume && chmod 770 /host_volumeます。 / host_volumeの背後にあるホスト上にディレクトリを作成するときに、Dockerが独自にそれを実行できるとしたらどうでしょうか。 このように、コンテナのルートとして上記の操作を実行するためだけにコンテナに追加のエントリポイントを提供するハックは必要なく、ルート以外のアカウントを使用してコードをいつでも実行できます。

@ibukanovああ、それは別のことです。
Dockerは、まったく意図的に、ホストディレクトリに変更を加えません。
#9092を実行すると、dockerがdirを作成した場合、それは通常のボリュームのように扱われます(つまり、コンテナー内のボリュームパスにあるすべてのものをホストにコピーし、コンテナー内と同じようにchmod / chownします)。

@ cpuguy83-ええと、dockerは、不足しているホストボリュームを作成するときに、ホスト上の何かを変更します。 しかし、#9092は、私のユースケースを実際に解決するかのように聞こえます。

@ cpuguy83は書いた:

そしてすぐに、コンテナ内のuid0はホスト上のuid0になりません...これにより、ファイルの所有権もさらに複雑になります。

これを追跡するための既存の問題はありますか? 見つかりませんでした。

ありがとう!

これを追跡するための既存の問題はありますか? 見つかりませんでした。

@dato 「ユーザー名前空間」を探します。 初期実装はここにあります: httpshttps://github.com/docker/docker/pull/11253

しかし、それ以前のさまざまな議論/問題があります:)

+1

だから私はみんなと同じ船に乗っていることを知っています:

私はnginxイメージを使用しており、ローカル開発のためにボリュームを/ usr / shared / nginx / htmlにマウントしています。 Nginxはwww-dataとして実行されますが、ボリュームは1000:staffとしてマウントされるため、 403 forbiddenを取得します。

@MrMMorris同じボートではないと思います-この問題は、コンテナ内(マウントされたボリューム上)に作成されたファイルが、sudoアクセスなしでコンテナの外部で読み取れない場合です。 www-dataユーザーは、マウントされたファイルへの読み取りアクセスのみが必要なので、ファイルに対してchmod a+rだけを実行できるはずです。

@ncjones chmod / chownはコンテナの権限に影響を与えないようです

私はこれが私の使用中に複数のポイントで機能したことを誓うので、私はとても混乱しています...

さて、これは恥ずかしいです...

1.3.0rc-1を作成するようにアップグレードした後(おそらくそうではない)、またはすべてのコンテナ/イメージを削除してdocker-compose up再度実行すると、すべてが修正されたようです...これ以上403 forbiddenありません

私はそれがどういうわけか以前に機能していることを知っていたので、私は古いrm -rf *アプローチを取りました。

また、この問題を何らかの方法で解決する必要があります。 分離する必要のある重いコンパイル作業を実行するために使用するDockerイメージがあります。 したがって、コンテナは上昇し、外部入力を受け取り、処理してからバイナリ(出力)を生成する必要があります。 適切な許可管理がなければ、これを機能させようとするのは悪夢でした。 私の画像はポータブルでなければならないので、ホストについて多くを推測することはできません。

@alercunhaあなたの場合、

@alercunha
Dockerコンテナにビルド出力をchownさせることで、ビルド設定でこの問題を回避しました。 Dockerfileには次のようなものが含まれます。

env USER_ID 1000
env GROUP_ID 1000
cmd bash -lc '\
  build.sh && \
  chown -R $USER_ID:$GROUP_ID build \
'

Dockerホストのユーザーの実際のuid / gidは、実行時にコンテナーに提供できます。 たとえば、Jenkinsビルドコマンドは次のようなものを使用します。

docker run \
  -e USER_ID=`id -u` \
  -e GROUP_ID=`id -g` \
  -v $basedir:/workspace

@motin rootとしてのビルドは、docker / buildrootを使用していくつかのサードパーティプロジェクトをビルドしているため、避けようとしています。 アイデアは、そのソースコードが私のビルド環境を台無しにすることに対してある程度の保護を与えることです。 したがって、rootとして構築することは良い考えのようには思えません。

@ncjonesありがとう! それは実際には良い考えであり、私の特定のケースでは解決策としてうまくいくかもしれません。

@alercunhaその場合、サードパーティのプロジェクトごとに個別の画像/コンテナを使用することを検討する価値があるかもしれません。 これは、たとえば、これらのサードパーティプロジェクトのそれぞれを構築するための公式のDockerイメージを提出した場合など、オープンソースコミュニティにより良い利益をもたらす可能性もあります。

www-dataにすべての特権を付与するには、次を使用できます。

RUN usermod -u 1000 www-data

マウントされたボリュームのDockerでジョブを実行しているときに問題が発生しました。 結果のファイルはrootが所有しており、dockerコマンドを実行しているユーザーが管理することはできません。 現在の回避策は、権限を修正するためにジョブの後に実行することです。

docker run -t --rm \
    -v $PWD:/usr/src/app \
    -w /usr/src/app \
    debian:wheezy chown -R $(id -u):$(id -g) ./

DockerFileのUSERコマンドで指定されたユーザーが所有するホストベースのマウントされたボリュームの権限をdockerに変更させることは可能ですか? 明らかに、アクセス許可は構成可能である必要がありますが、これをデフォルトの動作にすることができます。

@ mig-foxbat
私の目的では、ホストディレクトリが初めて作成されたときに、dockerがイメージのマウントポイントからホストディレクトリの所有権とアクセス許可を設定するだけで十分です。 ホストディレクトリがすでに存在する場合、Dockerはそれをそのままにしておくことができます。

@ mig-foxbat&@ ibukanovは、この問題を開いたときの必須の前提条件は、hostsファイルシステムのアクセス許可が変更されないことでした(_NFS_で実行できるのと同様の仮想コンテナ内マッピングがある場合など)。

コンテナ内の起動スクリプトで_chown_を実行することで、今日あなたがやろうとしていることを簡単に行うことができます。

今後のボリュームプラグインアーキテクチャが大好きですが、Dockerチームがこの機能を追加したいと思っています。 Dockerは、コンテナーでroot以外のユーザーがいるボリュームを使用するまでは正常に機能します。 次に、処理(ロギングなど)が機能しない場合は、ラップトップをスターバックスウィンドウから投げるか、上記のstackoverflowアイテムを見つけます。

+1非rootユーザーとしてアプリケーションを実行するコンテナーが必要ですが、この問題のために複雑になります。

LXCのid_map機能を使用してこの機能を実装してみませんか?

「id_map」(別名ユーザー名前空間のサポート)への回答が@thaJeztahによってすでに言及されていることに気づきました

権限を設定するには少し余分な作業が必要ですが、非ルートとして数十のコンテナを実行し、権限の問題を回避しています。 ほとんどのデータコンテナは、次のようなもので始まります。
ENVCONTAINER_USER領事
ENV CONTAINER_UID 312312
adduser -D $ CONTAINER_USER -u $ CONTAINER_UIDを実行します
mkdir -p / var / consul /を実行します
CMD chown $ CONTAINER_USER。$ CONTAINER_USER / var / consul /

実際の実行コンテナは、UID /ユーザー追加情報の設定に関して同様です。 これはいくつかの重複作業です(データコンテナーと実行コンテナーの両方にUIDを設定する必要があります)が、かなりマイナーです。 Dockerのアクセス許可またはマップのアクセス許可をその場で変更すると、かなり複雑になり、ユーザーはセキュリティの観点からより注意する必要があります。 私はまた、コマンドラインの複雑さを軽減するのに役立つものは何でも好きなので、すべてがdockerfileに自己完結している場合は、何が起こっているのかが少し簡単になります。

ある種のマッピングを使用してコンテナ内のホストファイルにアクセスしようとする上記の注意事項があります。 これは確かに危険な提案だと思います。 多くの場合、直接のホストマッピングなしでファイルを共有しようとするのがおそらく最善の解決策です。そうでない場合は、Dockerのセキュリティが多少逆転します。 それ以外の場合よりも権限が少ないコンテナではなく、ホストファイルへのルートレベルのアクセス権(多くの場合、ユースケースと推定される)を持つ非ルートとして実行されているコンテナについて話します。 私が感じるグループの許可または他の解決策は、ほとんどの状況で勝つはずです。

マウントされたディレクトリをchownし、suを介してサブコマンドを実行するエントリポイントシェルスクリプトを使用して、これを回避しました。

/ dataディレクトリーがホストからボリュームとしてマウントされるsolrコンテナーの例:

#!/bin/bash

chown -R $SOLR_USER:$SOLR_USER /data

su -c "$@" -m $SOLR_USER

_USER POLL_

_このディスカッションに変更があったときに通知を受け取る最良の方法は、右上の[購読]ボタンをクリックすることです。_

以下にリストされている人々は、ランダムな+1であなたの有意義な議論に感謝しています:

@jcercurati
@iangelov
@scue
@razvanphp
@幽霊
@andrerocker
@anandnalya
@ddopson
@hason
@hadim
@iyn
@cgrantcharovtp
@sandytrinh
@gomex
@DrBenton
@tehmaspc
@segphault
@avaz
@edavism
@ayeo
@stanislavb
@smebberson
@ tony-kerz
@msierks
@pdonorio
@ samsong8610
@ qm78
@joshughes
@roelvanduijnhoven
@vladimirbright
@ ava-dylang

これらのスレッドで何かを言うと、ユーザーは自動的にサブスクライブされます。したがって、追加で意図的にサブスクライブを解除しない限り、すべてのユーザーがサブスクライブされます。 (また、あなたがyourとして参照している_who_もわかりません)

これは間違いなく必須です。 DockerはUIDを適切に再マップする必要があります。 それ以外の場合、コンテナからホストOSボリュームに作成されたものはすべてrootが所有します。 回避策はひどいものです。コンテナ内のユーザーを変更すると、あらゆる種類の問題が発生し、どこでもchownする必要があり、Dockerfileは醜くなります。 そして、すべてのハードコーディングUIDの中で最悪の場合、コンテナーは移植できなくなります。

+1ファイルのユーザーIDを上書きしないようにするために、Dockerコンテナーとホストシステムの切り替えを避けたいので、この機能を高く評価します。

UIDのカスタマイズは現在可能ですが、次の制約の範囲内です。

  • コンテナに環境変数を介して必要なuidを受け入れるようにすることで、Uidのカスタマイズが可能です。 これにより、ホストはコンテナーが使用するuidを完全に制御できるようになり、追加の利点があります。複数の変数を同じuid値に設定できます。 マッピングは1:1である必要があるため、Uidの再マッピングは単一のホストuidへの複数のコンテナuidのマッピングをサポートできません。 たとえば、目的のマッピングが実際にアプリケーションをuid = 0として実行する必要がある場合、変数を挿入することでそれを行うことができますが、uidの再マッピングを介して行うことはできません。 上記の@ncjonesおよび@mitchcapperソリューションを参照してください。
  • ただし、ルートuid = 0は、再マッピングする場合を除いて、別の値に変更することはできません:#12648。

最近のほとんどすべてのWeb開発フレームワークには、プロジェクト内にログフォルダーとキャッシュフォルダーがあり、プロジェクト構成で定義され、マウントされたボリュームを介して共有されます。 最初にvboxfsを使用しましたが、遅すぎました。 docker-machine-nfsがNFSマウントを作成するのを見つけましたが、高速ですが、コンテナー内のWebファイルは502:dialoutによって所有されており、chmodまたはchownできないため、Webアプリは実行されません。 docker vagrant boxを試しましたが、すべての異なるenv変数と構成のvagrantが必要であり、docker-machineではまだ機能しません。 短期間の手動プロセスであっても、ユーザー502をwww-dataなどに追加するための回避策はありますか? それが私がビジネスに必要なすべてです!

+1

これに従う人のために; 現在、バインドマウントされたファイルの所有権を再帰的に変更する実験的な機能のPRがあります。 ただし、この機能はホスト上のファイルを変更するため、注意して使用する必要があります(すべての場合に必要なものとは限りません)。 https://github.com/docker/docker/pull/14632 (およびhttps://github.com/docker/docker/pull/16767)を参照して

+1

ちなみに、ACLを使ってこの問題を解決しました

@kvaps 、詳しく説明しますか?

@positaは、私の賭けは@kvapsで話しているPOSIX ACLを。 私が正しければ、それはOPリクエストと同じではありません。

@ posita@ denydias 、長い回答でごめんなさい。 はい、私はこれについて話している。
私はowncloud、samba、minidlnaのような多くのコンテナを持っています。 誰もが異なるuidとgidで動作します。
それらはすべて同じファイルで動作します。 誰もがファイルを読み書きできるものを、 aclオプション付きのファイルシステムをホストマシンにマウントし、 chownコマンドのように、このファイルのuidおよびgid権限をすべての人に簡単に与えました。

# give access for owncloud (apache uid 33):
setfacl -R -m "u:33:rwx" /data
# give access for samba (uid 1000):
setfacl -R -m "u:1000:rwx" /data
# give access for minidlna (uid 997):
setfacl -R -m "u:997:r-x" /data
# preserve this permissions for new files and folders:
setfacl -R -d -m "u:33:rwx" /data
setfacl -R -d -m "u:1000:rwx" /data
setfacl -R -d -m "u:997:r-x" /data

@kvaps 、コマンドsetfaclDockerfileでは機能しません。 例:

FROM nginx

ADD data/conf /etc/nginx

RUN mkdir -p /etc/nginx/sites-enabled

VOLUME /etc/nginx

RUN setfacl -dR -m u:1000:rwx /etc/nginx && setfacl -R -m u:1000:rwx /etc/nginx

結果:

root<strong i="12">@3975ac4fba98</strong>:/etc/nginx# getfacl sites-enabled/
# file: sites-enabled/
# owner: root
# group: root
user::rwx
group::r-x
other::r-x

ACLは、ホストマシンにマウントしてsetfaclを実行した後にのみ機能します。 Dockerバージョン:

Client version: 1.7.1
Client API version: 1.19
Go version (client): go1.4.2
Git commit (client): 786b29d
OS/Arch (client): linux/amd64
Server version: 1.7.1
Server API version: 1.19
Go version (server): go1.4.2
Git commit (server): 786b29d
OS/Arch (server): linux/amd64

これは正しく行うのが非常に簡単で、失敗するのも非常に簡単です。 だからそれを台無しにしないでください!
これを行う正しい方法は次のとおりです。コンテナが最初に実行されるときに、ホストはコンテナが使用する必要のあるuidを注入します(すでに前述したように)。
これを行うためのより悪い方法は、コンテナがホストにuid要件を課すことを期待することです。 これは間違っている、間違っている、間違っている。 たとえば、共通のマウントを共有する2つのコンテナについて考えてみます。1つのコンテナは提供するファイルを書き込み、もう1つのコンテナはhttpdを実行してファイルを提供します。 さて、これらのコンテナの両方がuidに対して競合する定義を持っている場合、このシステムは最悪の場合壊れるか、せいぜい不十分になります。 設定されているACLはホストにとって意味がなく、必要以上に幅が広い可能性があります。これは、セキュリティの問題になっていることを意味します。 これをしないでください! それを正しい方法で行います。

同意しました。 UID間のマッピングをコンテナーに残すことは、十分な解決策です。 Dockerが例を挙げて先導し、公式のDockerイメージでそのようなUID / GIDマッピングをサポートすることを望んでいました。

chown実行しなくても、ます

@ncjonesのソリューションに近いものを使用しましたが、ホスト上でファイルを変更したくないので、 chownファイルを使用したくありません。 そこで、コンテナの起動時にUIDを変更することにしました。

Dockerfile専用ユーザーを作成します:

RUN adduser --no-create-home --disabled-login --gecos "" username --uid 1000

Dockerfile起動スクリプトを定義します:

CMD ["/run.sh"]

/run.shスクリプトに次の行があります:

usermod -u $USER_ID username

これで、コンテナの起動時にUSER_ID選択できます。

docker run -e USER_ID=$(id -u)

新しいdockerfile引数を使用してこれを解決することができました。 コンテナを作った後は特別なことをする必要がないので、シェアしたいと思いました。 (Docker 1.9が必要)

Dockerfileの場合:

# Setup User to match Host User, and give superuser permissions
ARG USER_ID=0
RUN useradd code_executor -u ${USER_ID} -g sudo
RUN echo 'code_executor ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
USER ${USER_ID} 

次に構築するには:

docker build --build-arg USER_ID=$(id -u)

他のすべては通常通りです:)

編集:
私は間違った問題についてこの投稿を書きました(それはboot2dockerに関連した別のものでした)。
ごめん。

@ pa-de-solminihac usermod -u $USER_ID usernameusernameのユーザーIDを変更し、 usernameのHOMEにあるファイルの所有権の変更をトリガーしますが、以前はすべてのファイルが所有されていました彼のHOMEの外にあるusernameは、別のユーザーに属しているため、おそらく読み取り/書き込み不能になります。

@riquito Dockerfileで作成された専用ユーザーで使用します:

adduser --no-create-home --disabled-login --gecos "" username --uid 1000

したがって、以前にusernameが所有していたファイルはありません。 だから問題ないと思います;)

参考までに、 setfaclは、OSXまでさかのぼるボリュームでは機能しません。

root<strong i="7">@0da3c867240d</strong>:~# setfacl --default --recursive --modify u:500:rwx --modify g:500:rwx /opt/test
setfacl: /opt/test: Operation not supported

(この場合、 /opt/testはOS XからDockerマシンとBoot2Dockerを介してホストされます。boot2docker/ boot2docker#581も参照してください。)

@posita boottodockerイメージをホストするためにvirtualboxを使用していますか? もしそうなら、それは実際にはvirtualboxが共有フォルダを行う方法の制限かもしれません。 仮想ボックスの共有フォルダを介して、通常の透過性を実行するのに多くの問題がありました。

@ ava-dylang、それは良い点です。 上記は、 Parallelsドライバーを備えたDocker Machineを介したもの

FWIW、ユーティリティのScubaでファイルの所有権に問題がありました。

ホストの呼び出し元ユーザーと同じUID / GIDを持つユーザーをコンテナーに作成する「init」スクリプトを追加することで、この問題を回避しました。 JonathonReinhart / scuba#11およびJonathonReinhart / scuba#13を参照してください。

これで、コンテナで作成されたファイルは、ホストで作成されたものとまったく同じように見えます。

_更新:_それが問題を引き起こしました(JonathonReinhart / scuba#22)。 代わりに、ホストユーザーのuid / gidに基づいて独自の/etc/passwdとその友達を生成し、コンテナーに挿入することで修正しました(JonathonReinhart / scuba#24を参照)。

+1

ホストがマルチテナントモードで実行されている場合に、保守性と安全性を高めるため。

ホストからコンテナへのWordpress全体をボリュームで共有すると、このようなWordpressのインストールで権限の問題が発生しました。

私のスタックには、基本的な変更を加えたDebianであるベースイメージがあり、他のすべてのイメージはこのイメージから構築されます。

ベース画像には、次の部分があります。

### Start of Nginx WEBSERVER setup
RUN mkdir -p /var/www
# Modify www-data user and set UID, GID to 500
# https://muffinresearch.co.uk/linux-changing-uids-and-gids-for-user/
RUN groupmod -g 500 www-data \
    && usermod -u 500 www-data \
    #&& `find / -user 33 -exec chown -h 500 {} \;` \
    #&& `find / -group 33 -exec chgrp -h 500 {} \;` \
    && usermod -g 500 www-data \
    && chown -R www-data:www-data /var/www \
    && chmod g+s /var/www
### End of Nginx WEBSERVER setup

www-dataは、phpまたはnginxのインストールでは作成されません。 これは、Debianおよびおそらく他のディストリビューションでデフォルトで定義されているユーザー/グループです。 一部のPHP、Nginxのインストールでは、構成ファイルでこのユーザーを使用することをお勧めします。

ホストユーザーのUID / GIDが500(ほとんどのデフォルトのLinuxの最初の非rootユーザーのUID / GIDは500または1000)の場合、このスクリプトはwww-dataユーザーのUID / GIDを33から500に変更します。ホストから何かを共有すると、Dockerはwww-dataユーザーが所有するファイルとフォルダーを考慮します。

PHP-FPM設定ファイルで、ユーザーとグループもwww-data設定します。

nginx Dockerfileで、これも設定する必要があります。

# Allow Nginx to access /var/run/php-fpm/php-fpm.sock
RUN usermod -aG www-data nginx

このようにして、 nginxユーザーはwww-dataが所有するファイルにアクセスできます(nginxのユーザー名はnginx構成ファイルで定義できます)。

このハックの後、私のWordpressインストールには権限の問題はありません! すべてのファイルはホスト上にあり、Wordpressの更新は問題なく機能します!

@DJviolinこのような問題がWordpressチュートリアルの適切な場所であるかどうかは

  1. あなたが投稿したものは、インストールについて多くの仮定をしています-すなわち、UID / GID値、ユーザー名とグループ名など。それはディストリビューション間でひどく移植可能ではありません。
  2. さらに重要なことに、Wordpressのインストール全体に誰でも書き込み可能な(0777)アクセスを許可することは非常に危険であり、公式のWPドキュメントでは明示的に推奨されていません。 さらに、これらすべてがホストからマウントされた状態で、インターネットからの任意のアップロードが_host_ファイルシステムに書き込むことを許可しただけです。

@jantman申し訳ありませんが、私の悪いです。 最初のハックで権限の問題も解決したようです。 デフォルトの権限を変更する必要はありません。

明らかに、誰もが自分のホストユーザーUID:GIDを見つけて、これに従って構成を変更する必要があります。 さらに、クエスト内の既存または新規のユーザーと接続します。 鉱山は、生きているスタックの実用的な例です。

dockerがこの問題の解決策を提供しないまで、前提条件は維持されます。

私の解決策は@JonathonReinhartまたは@ pa-de-solminihacのものと同じです。

これを行うには、ローカルボリュームを作成します。これは、マスターです。

これを修正済みとして閉じます。

こんにちは私はまた私のdockerfileで回避策を作らなければなりませんでした:

...
COPY start.sh /root/start.sh
CMD /root/start.sh

そしてstart.shで

usermod -u $USER_ID www-data
exec php-fpm

$ USER_IDを環境パラメーターとして挿入できるため、変更せずにそのDockerイメージを使用できます。

とにかく、私はその種のもののためのより多くの組み込み機能があるべきだと思います、そして@calaveraによって提案されたそのローカルボリュームをどのように使うのか疑問に思っています、誰かが例を提供できますか?

@ keywan-ghadami私もローカルボリュームに戸惑っていました。 問題は、最初にファイルシステムを作成する(またはtmpfsを使用する)必要があることです。 したがって、/ var / lib / dockerは使用しません。 実際、バインドマウントはuidオプションをサポートしていないため、既存のFSのサブディレクトリを使用することはできません。 ローカルボリュームの目的がわかりません。 FSを自分で作成してマウントしてから、通常のホストボリューム( -v my-created-fs:container-mount-point )を使用することもできます。

私はこのスレッドにかなり遅れていますが、この問題は解決されていますか? ここで参照されているさまざまな問題すべてから100%明確ではありません。 @brthorは私が見ることができるものから最良の解決策を持っているようですが、Dockerfileに追加して、舞台裏でより簡単に実行できるコマンドラインオプションが含まれています。

私にとって、UIDとGIDをハードコーディングすることは、環境間の移植性にとって悪い考えであり、コンテナーを起動したり、イメージを構築したりするたびにコマンドライン引数を追加する必要はありません。 Dockerfile。 Dockerfileまたはdocker-compose.ymlを介して、ある種の「ホストからのマップuid」オプションを指定できる単純なオプションはありませんか?

すでにそこに良い解決策があるかもしれませんが、私はドキュメントやこのスレッドからこれを本当に理解することはできません。

@alvinchevolleauxに感謝します。https://github.com/dotnet/cliのCIに上記で投稿したソリューションを数か月間正常に使用していることを確認できます。

それをお勧めします!

@brthorはい、それは私が行ったことですexport USER_ID=$(id -u)を.bash_profileに追加したので、さまざまな環境ですべて自動になります。 どうもありがとう。

上で説明したように、ホームフォルダーからコンテナーにコンテンツを共有する場合は、自分と同じUIDを持つユーザーアカウントを追加します。 UIDが1000でない場合に対処するための秘訣は、次のとおりです。各ユーザーがDockerfileから独自のDockerイメージを作成すると想定しています。

Dockerfileは次のものが含まれている必要があります。

RUN useradd --uid 1000 -m vagrant
USER vagrant

定数1000は、_gitfilter_を使用して実際のUIDに置き換えられます。 ホストで以下を実行します。

git config filter.uidfix.smudge "sed s/1000/$UID/g"
git config filter.uidfix.clean "sed s/$UID/1000/g"

最後に、 .gitattributesファイルを追加してgitフィルターを適用します。

Dockerfile filter=uidfix

これは、ファイルを_smudging_してDockerfileをチェックアウトするときに、 1000を実際のUIDに置き換えることで機能します。 コミットすると、Gitはファイルを_clean_します( 1000を元に戻します)。 コンテナで実行されるコマンドはすべて、正しいUIDを持つvagrantユーザーとして実行されます。

ここで提供されるすべてのソリューションは回避策にすぎないため、このチケットを再度開く必要があります。
https://github.com/rocker-org/rocker/blob/master/rstudio/userconf.shで、文書化された、より完全なソリューションを見つけました
実行時引数を使用するため、gitフィルターでは使用できないビルド前のイメージを使用できます。

@calavera私はあなたの解決策を理解していません。

例えば

$ mkdir /tmp/test
$ sudo docker volume create --name=test -d local --opt type=nfs --opt device=/tmp/test:/data --opt o=notime,nosuid,uid=11459,git=11459
$ sudo docker run -t -i -v test:/tmp fedora bash -i
[.. $] touch /tmp/foo.txt
[.. $] exit
$ ls -la /tmp/test

/ tmp / testディレクトリを見ると、ファイルがありません。 / tmp / testフォルダーがコンテナーにマウントされているようには見えません...むしろ、コンテナーボリュームを作成しています。 それは本当に欲しくないです。

何が有効な--optオプションであるかを教えてくれるドキュメントが見つかりません。 だから私はこれがどのように機能すると思われるかについて本当に推測しています。

この号を再度開いてください。 新しいローカルドライバは、選択したユーザーIDでローカルホストディレクトリをマウントする問題にまったく対処していないようです。

@calavera
ローカルホストボリュームでrootとしてファイルがドロップされる問題を解決する方法についてコメントしていただけますか? 特にCIシナリオにdockerを使用している場合、この問題が頻繁に発生します。

リンクされたPRを見ると、すぐには明らかなことは何もわかりませんが、何かが足りないと確信しています😄

私は、docbill / docker-forceなど、この回避策のバリエーションをコンテナーで使用しています。 しかし、私には、よりクリーンなソリューションは、スカッシュルートの実行のみを担当するコンテナーであると思います...

ローカルにbindfsのようなものを使用すると役立つはずです。 -o map = $(id -u)/ root:@ $(id -g)/ @root (ユーザー名前空間がないと仮定)を使用して実行でき、ファイルが所有されている間は、コンテナーの外部にあるファイルとして表示されます。その中のルート。

@ktosiekありがとう、それは可能性があるように聞こえます。 docker runコマンドまたはコンソールセッションの完全な例を投稿できますか?

誰かがこの問題に関するステータスの更新を投稿できますか?「修正されない」としてクローズされましたか、それとも実際に実装されましたか? スレッドがかなり長いので、解像度が一目でわからないのでご容赦ください。

@quinncomendanthttps://github.com/docker/docker/issues/7198#issuecomment-191990887を参照して
動作しない場合は報告してください。

@ LK4D4に感謝します。

要約すると、この問題は、マウントがlocalボリュームドライバーを選択できるようにする修正で解決されました。

私の知る限り、ボリュームとしてマウントされた_host-directory_のuser:groupを設定するオプションはありません(そのオプションが存在する場合は修正してください。これが私がここで学んだことです)。

@quinncomendant正解; ホストディレクトリをバインドマウントするときは、コンテナがそのまま存在するファイルを使用するようにします。これには、アクセス許可が含まれます。 これらのアクセス許可を変更する場合は、バインドマウントする前に、ホストで変更する必要があります。

@quinncomendantまたは簡単に言えば、これは修正されません。
提供されたソリューションは、実際には問題に対処するために何もしません
報告されており、その問題を解決する計画もありません。

17時20時2016年7月6日、SebastiaanバンStijn [email protected]
書きました:

@quinncomendanthttps ://github.com/quinncomendant正解; いつ
コンテナが使用するファイルを使用するホストディレクトリをバインドマウントします。
パーミッションを含む現状のままです。 それらを変更したい場合
権限については、バインドマウントする前に、ホストで行う必要があります


あなたがコメントしたのであなたはこれを受け取っています。
このメールに直接返信し、GitHubで表示してください
https://github.com/docker/docker/issues/7198#issuecomment -230909967、またはミュート
スレッド
https://github.com/notifications/unsubscribe/ADBcWLihVjI1FoSMLKu7DyhwFOpGX0KKks5qTBwMgaJpZM4CQMjR

これは修正されない問題のようです。 コンテナ化の_開発_の側面は見過ごされ続けており、それでもハックを書く必要があるようです。

私がサポートしている開発者がプロ​​ジェクトファイル生成コマンドをコンテナ内からホストにマウントされたボリュームに実行しているため、この問題に特に遭遇しました(これらのツールをホストにインストールすると、コンテナを使用する目的が完全に無効になりますよね?)。

彼らはこれらのファイルをすばやく反復したいと思っていますが、このスレッドの他の人が指摘しているように、コンテナーが実行されているuid / gidとして書き出されるため、ホスト上で正しくチャウニングしてさらに操作する必要があります(たとえばIDE)。

このような場合、一時的なuid / gidをシムする_docker固有の_方法が本当に必要です。

@bojこれは、スキューバの開発中に遭遇した正確なシナリオです。 私の現在のソリューションは、起動時に、ホストユーザーと同じuid / gidを持つユーザーをコンテナー内に作成します。 これは最も単純な解決策ではありませんが、うまく機能します。

@JonathonReinhartありがとう、あなたは私に少しインスピレーションを与えてくれました。

私はこのようにホストから呼び出されるスクリプトラッパーを書くことになりました(この場合はdjangoを使用します):

# bin/manage.py
#!/bin/sh

docker run -v $(pwd):/usr/local/prj -it --entrypoint="/usr/bin/python3.4" -w /usr/local/prj -u $(id -u):$(id -g) prj src/prj/manage.py $@

@bojそのソリューション( -u $(id -u):$(id -g) )の潜在的な問題は、コンテナー内のそのuid / gidの/etc/passwdまたは/etc/groupにエントリがないことです: https:// github .com / JonathonReinhart / scuba / issues / 11

@JonathonReinhart注目。 この特定のケースでは、開発者のホストに書き出されたファイルと、それらがホストユーザーと同じ権限を持っていることだけを気にします。

実行時に実際に何が起こるかについて心配する必要はありません。私が本当に必要としていたのはこれだけでした。

@JonathonReinhart

コンテナ内のソフトウェアが/ etc / passwdまたは/ etc / groupにエントリを必要とする場合は、それらをイメージで誰でも書き込み可能にし、起動時に必要なエントリをそこに追加します。

したがって、 @ JonathonReinhart (uid / gidマッピング)によって言及されたソリューションはこれを解決します。

これはrunc(https://github.com/opencontainers/runc/blob/8c9db3a7a5145f6b26c8051af319eee6f72c9ca8/libcontainer/configs/config.go#L19-24)ですでにサポートされているようです。 Dockerには、デーモン用のuserns-remapがあります。ここでは、基本的に、よりきめ細かい(デーモンレベルではなくコンテナーレベル)必要があります。これをサポートすることに関心/計画はありますか?

このdocker-compose.ymlは機能しません:

version: '2'

services:
  app:
    build: ./app
    container_name: myapp
    volumes:
      #- "../app:/root/www/myapp:rw"
      - myapp:/root/www/myapp:rw

volumes:
  myapp:
    driver: local
    driver_opts:
      o: uid=500
      device: ../app

誰かが理由を教えてくれますか? 私は公式ガイドラインに従います: https

ホストから名前付きボリュームをアタッチすることは可能ですか? driver_optsを使用すると、 uid (およびおそらくgid ?)を定義できます。

+1

+1

@lazyuser @ xiaods + 1で停止してください。 それはそれらすべての--->参加者をスパムする以外に何も達成しません。

@bamarniはい、新しいユーザー名前空間機能でこれを解決できると思いますが、docker runコマンドラインで渡されるUID / GIDです。 その場合、ファイルは適切なユーザーが所有するコンテナから「出てきます」。

@lazyuser @ xiaods @ JonathonReinhart問題の説明の下にある+1ボタンをクリックする必要があります

または、通知のみが必要な場合は、右側の[購読]をクリックしてください...

@JonathonReinhart :確かに、私はドキュメントをもう一度

注:Dockerは、エンジンインスタンスで実行されているすべてのコンテナー間で、ローカルキャッシュからのイメージレイヤーを共有するため、デーモンごとの単一マッピングの制限が今のところ適用されています。 ファイルの所有権は、同じレイヤーコンテンツを共有するすべてのコンテナーで同じである必要があるため、コンテンツがダウンロードされた後のコンテナーの実行に遅延が発生しないように、Dockerプルのファイル所有権をデーモンのユーザーおよびグループのマッピングにマッピングすることが決定されました。 この設計では、ユーザーの名前空間を無効にした場合にユーザーが期待するのと同じパフォーマンスを、Dockerプル、Dockerプッシュ、およびコンテナーの起動で維持します。

_(https://docs.docker.com/engine/reference/commandline/dockerd/#/daemon-user-namespace-options)_

親愛なる@ JonathonReinhart 、@ pa-de- nalipaz
それだけで問題に関係のないコメントを残さないように私や他の人を教育するためのあなたの努力に感謝します! 参考までに、Githubは、少なくともコメントせずに、サブスクライブしている問題を検索することを許可していません。 詳細については、 https://github.com/isaacs/github/issues/283を参照して

スパムをお詫びします。 初めてそれは前述のgithubバグの回避策でした、そして今回は状況の皮肉を与えることに抵抗できませんでした。

私はinotifywaitを使用してこれを解決し

RUN export DEBIAN_FRONTEND=noninteractive \
  && apt -y update \
  && apt -y install inotify-tools \
  && inotifywait -m -r /mount -e create --format '%w%f' \
    | while read f; do chown $(stat -c '%u' /mount):$(stat -c '%g' /mount) $f; done

これは、ディレクトリ/ mountに作成された新しいファイルまたはディレクトリを監視するようにinotifywaitに指示することで機能します。 それに気付くと、所有権を/ mountフォルダーと同じユーザーとグループに変更します。 ホストユーザー/グループがコンテナーに存在しない場合に備えて、両方の整数表現を使用しました。 コンテナ内では、すべてがrootとして実行されるため、誰がコンテナを所有しているかは関係ありません。 コンテナの外部では、ホストファイルシステムは/ mountにマウントされたディレクトリと同じ所有権を示します。

既存のファイルとディレクトリの所有権を保持するために、新しく作成されたファイルとディレクトリの所有権のみを設定するように意図的に設計しました。 ファイルシステムがマウントされるたびにchown-Rステートメントですべてを吹き飛ばすよりも安全です。 プロジェクトで統一された権限が機能し、より効率的に実行されるより単純なソリューションが必要な場合は、 inotify-hookableを検討してください

警告:サブディレクトリごとに1つのinotifyウォッチが確立されるため、ユーザーごとのinotifyウォッチの最大数に達する可能性があります。 デフォルトの最大値は8192です。 / proc / sys / fs / inotify / max_user_watchesに書き込むことで増やすことができます。

@ codekitchen-ws別の警告:ファイルは、作成後、所有者が変更される前に移動される可能性があります。 シェルによっては、 "$f"も引用する必要があります(パスでの単語の分割を防ぐため)。

+1

@briansrepoそれは興味深いアプローチです。 これがDockerfile RUNステートメントにある場合、ビルド時に実行されます。 実行時にdocker runユーザーをどのように知ることができますか?

@btiernayありがとう! イメージを起動したユーザーのUIDは使用しません。 これは、/ mountにマウントされているホストディレクトリのホストユーザーとホストグループを具体的にコピーします。 他のファイルやサブディレクトリは調べません。 権限がホストシステム上で書き込み可能なものに設定されていることを確認するのはユーザーの責任です。

例:ホストディレクトリ/ var / www / htmlがbrian:www-dataによって所有されていると仮定しbrian:www-dataが所有し

その例に基づいて、 www-data:www-dataが所有するホストディレクトリ/ var / www / html / uploadがあるとしbrian:www-dataによって所有されていることにwww-data:www-dataではなくます。 brian:www-dataが所有してい

TL; DR:マウントされたホストディレクトリをuser:groupに変更することにより、使用するuser:groupを渡します

@briansrepo説明ありがとうRUN内でどのように機能するかをまだ理解していません。 これは、コンテナが実行されるときにバックグラウンドで実行する必要があると思います(つまり、 docker run )。

@btiernay私もこのアイデアが好きです。
@briansrepo少なくとも、コンテナから何が起こるかをカバーしています。
ビルドプロセスは、次のような方法で対処できます。

RUN usermod -u 1000 www-data

ただし、これらはまだ回避策です。

私のLEMPスタックでは、ベースのDockerfileに次のNginx事前設定があります。

### Start of Nginx WEBSERVER setup
RUN mkdir -p /var/www
# Modify www-data user and set UID, GID to 500
# https://muffinresearch.co.uk/linux-changing-uids-and-gids-for-user/
RUN groupmod -g 500 www-data \
    && usermod -u 500 www-data \
    && usermod -g 500 www-data \
    && chown -R www-data:www-data /var/www \
    && chmod g+s /var/www
### End of Nginx WEBSERVER setup

これは、uid、gidが500、nginxを取得するホストsshセッションから新しく作成されたすべてのファイルが、最終的にこれらのファイルにアクセスできなくなるハックです(IDが500のユーザーまたはグループがコンテナーに存在しなかったため)。 sshセッションからホスト上の共有ボリュームに新しいファイルをコピーし、後でこのコンテナにdocker execをコピーするときに、 www-dataユーザー用に作成する必要のあるuid、gid番号を確認できます。 uid、gidのファイルを見てください。

私が見つけた問題は、ホストマシンの共有フォルダー(DigitalOceanのCoreOSインスタンスのようにsshセッションでアクセスした)に新しいファイルをコピーした場合、Nginxはそれらの新しく作成されたファイルにアクセスできません。 したがって、特権との絶対的な互換性が必要な場合は、コンテナーの作成時にWebサーバーファイルをDockerコンテナーに共有する必要があります(少なくとも1年前、共有ボリュームでこれらのuid、gidの問題が発生したときはそうでした) 。

または、ファイルをnginxコンテナーと共有するdockerコンテナーにsshサービスをインストールすることもできます。これにより、ファイルをコピー/変更すると、正しいuid、gidが取得されます。 しかし、これは、「DockerはVMではない」ため、sshセッションの代わりにdocker inspectを使用する必要があるDockerのベストプラクティスに反します(簡単すぎる解決策ですよね?)。

私の考えでは、Dockerコンテナーはサービスまたは実行可能ファイルのように機能する必要があり、必要がない場合はWebサーバーファイルを人質にするべきではありません。 データベースは別の種類のものです(時々)が、静的、ウェブサーバー、データベースファイルのすべてがコンテナの外にある同じ聖杯コンテナインフラストラクチャを実現できない理由がわかりません(ただし、コンテナはそれらを変更し(削除、作成、変更など)、ホストからの特権の問題なしに変更することもできます。

docker volume create --optを使用すると、uid、gidを定義できますが、 docker-composeは当てはまりません: https

uid / gidをマッピングするには、クロスプラットフォームのgo-to(gosuではない)ソリューションが本当に必要です。 この問題だけでも、Dockerが初心者に認識される方法に大きな損害を与えます。

この問題の回避策を作成し、ビルド時に設定されたDockerコンテナーのユーザー/グループとファイルのアクセス許可を、コンテナーが実行時に開始されたUID / GIDに変更します。

プロジェクトとインストールの手順は次の場所にあります//github.com/boxboat/fixuid

例:Dockerコンテナーは、ユーザー/グループdockeruser:dockergroupをUID / GID 1000:1000として使用して構築されました。 ホストはUID / GID 1001:1002として実行されています。 画像はdocker run -u 1001:1002ます。 fixuidは:

  • dockeruser UIDを1001に変更します
  • dockergroup GIDを1002に変更します
  • 古いdockeruser:dockergroupすべてのファイル権限を1001:1002に変更します
  • コンテナ内の$ HOMEをdockeruser $ HOMEに更新します
  • コンテナとホストのUID / GIDが一致し、ホストマウントのコンテナで作成されたファイルが一致するようになりました

ENTRYPOINTとして、または起動スクリプトの一部として実行できます。 これは、 setuidビットを使用してrootが所有するバイナリとしてコンテナにインストールされ、適切な変更を行うために特権をエスカレートします。 開発コンテナでのみ使用する必要があります。

これが有用であることが判明した場合、Dockerエンジンはdocker runフラグを介してロジックの一部またはすべてを組み込むことができる可能性があります

docker volumeを使用して解決しました。

@hasharどうやって? plsの例を挙げていただけますか

それで、 gosuとエントリポイントスクリプトを使用する以外に、これに対する解決策はまだありませんか?!

今のところ、Dockerチームがこれについて公式に更新するまで、この回避策として2つのオプションがあるようです。

これがまだ問題であるというような残念。 理論的にはuserns-remapがありますが、ユーザーフレンドリーではありません。

このページは役に立ちましたか?
0 / 5 - 0 評価