web-dev-qa-db-fra.com

Exécution en tant qu'utilisateur hôte dans un conteneur Docker

Dans mon équipe, nous utilisons des conteneurs Docker pour exécuter localement les applications de notre site Web pendant que nous développons sur celles-ci.

En supposant que je travaille sur une application Flask à app.py avec des dépendances dans requirements.txt, un flux de travail ressemblerait à peu près à ceci:

# I am "robin" and I am in the docker group
$ whoami
robin
$ groups
robin docker

# Install dependencies into a docker volume
$ docker run -ti -v `pwd`:`pwd` -w `pwd` -v pydeps:/usr/local python:3-slim pip install -r requirements.txt
Collecting Flask==0.12.2 (from -r requirements.txt (line 1))
# ... etc.

# Run the app using the same docker volume
$ docker run -ti -v `pwd`:`pwd` -w `pwd` -v pydeps:/usr/local -e FLASK_APP=app.py -e FLASK_DEBUG=true -p 5000:5000 python:3-slim flask run -h 0.0.0.0
 * Serving Flask app "app"
 * Forcing debug mode on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 251-131-649

Nous avons maintenant un serveur local qui exécute notre application, et nous pouvons modifier les fichiers locaux et le serveur sera actualisé au besoin.

Dans l'exemple ci-dessus, l'application s'exécute en tant qu'utilisateur root. Ce n'est pas un problème, sauf si l'application réécrit les fichiers dans le répertoire de travail. Si tel est le cas, nous pourrions nous retrouver avec des fichiers (par exemple, quelque chose comme cache.sqlite ou debug.log) dans notre répertoire de travail appartenant à root. Cela a causé de nombreux problèmes aux utilisateurs de notre équipe.

Pour nos autres applications, nous avons résolu ce problème en exécutant l’application avec l’UID et le GID hôte - par exemple. pour une application Django:

$ docker run -ti -u `id -u`:`id -g` -v `pwd`:`pwd` -w `pwd` -v pydeps:/usr/local -p 8000:8000 python:3-slim ./manage.py runserver

Dans ce cas, l'application s'exécutera en tant qu'utilisateur non existant avec l'ID 1000 à l'intérieur du conteneur, mais tous les fichiers écrits dans le répertoire Host finiront par appartenir correctement à la robin utilisateur. Cela fonctionne bien à Django.

Cependant, Flask refuse de s'exécuter en tant qu'utilisateur non existant (en mode débogage):

$ docker run -ti -u `id -u`:`id -g` -v `pwd`:`pwd` -w `pwd` -v pydeps:/usr/local -e FLASK_APP=app.py -e FLASK_DEBUG=true -p 5000:5000 python:3-slim flask run -h 0.0.0.0
 * Serving Flask app "app"
 * Forcing debug mode on
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
Traceback (most recent call last):
...
  File "/usr/local/lib/python3.6/getpass.py", line 169, in getuser
    return pwd.getpwuid(os.getuid())[0]
KeyError: 'getpwuid(): uid not found: 1000'

Est-ce que quelqu'un sait s'il y a un moyen que je puisse soit:

  • Assurez-vous que Flask ne vous inquiétez pas de l'ID utilisateur non attribué, ou
  • D'une manière ou d'une autre, attribuez de manière dynamique l'ID utilisateur à un nom d'utilisateur au moment de l'exécution, ou
  • Sinon, autorisez l’application de menu fixe à créer des fichiers sur l’hôte en tant qu’utilisateur hôte?

La seule solution à laquelle je puisse penser maintenant (super hacky) consiste à modifier les autorisations de /etc/passwd de l'image du menu fixe pour qu'elles soient en écriture, puis d'ajouter une nouvelle ligne à ce fichier lors de l'exécution pour affecter le nouvel UID/Paire GID à un nom d'utilisateur.

3
Robin Winslow

Cette réponse était posté sur StackOverflow par Robert :


Vous pouvez partager le fichier passwd de l'hôte:

docker run -ti -v /etc/passwd:/etc/passwd -u `id -u`:`id -g` -v `pwd`:`pwd` -w `pwd` -v pydeps:/usr/local -p 8000:8000 python:3-slim ./manage.py runserver

Ou ajoutez l'utilisateur à l'image avec useradd, en utilisant /etc comme volume, de la même manière que vous utilisez /usr/local:

docker run -v etcvol:/etc python..... useradd -u `id -u` $USER

(id -u et $ USER sont tous deux résolus dans l'hôte shell, avant que le menu fixe reçoive la commande)

0
Robin Winslow