W moim zespole używamy kontenerów Docker do lokalnego uruchamiania naszych aplikacji internetowych, podczas gdy pracujemy nad nimi.Uruchamianie jako użytkownik hosta w kontenerze Docker
Zakładając pracuję nad app kolbie w app.py
z zależnościami w requirements.txt
, przepływ pracy będzie wyglądać mniej więcej tak:
# 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
Teraz mamy lokalnego serwera z uruchomionym naszej aplikacji, a my możemy zrobić zmiany w plikach lokalnych, a serwer odświeży się w razie potrzeby.
W powyższym przykładzie aplikacja kończy pracę jako użytkownik root
. Nie stanowi to problemu, chyba że aplikacja zapisze pliki z powrotem do katalogu roboczego. Jeśli tak, to możemy skończyć z plikami (np. Takimi jak cache.sqlite
lub debug.log
) w naszym katalogu roboczym należącym do root
. To spowodowało wiele problemów dla użytkowników w naszym zespole.
W przypadku innych naszych aplikacji rozwiązaliśmy ten problem, uruchamiając aplikację z użytkownikiem hosta: UID i GID - np. dla aplikacji 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
W tym przypadku aplikacja zostanie uruchomiona jako nieistniejącego użytkownika o ID 1000
wewnątrz pojemnika, ale wszystkie pliki zapisywane w katalogu hosta kończy się prawidłowo posiadaniu przez robin
użytkownika. Działa to dobrze w Django.
Jednak Kolba odmawia pracy jako nieistniejącego użytkownika (w trybie debugowania):
$ 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'
Czy ktoś wie, czy jest jakiś sposób, że mogę albo:
- Bądź Flask nie martwić się o nieprzypisany identyfikator użytkownika lub w jakiś sposób dynamicznie przypisać identyfikator użytkownika do nazwy użytkownika w czasie wykonywania, lub
- W przeciwnym razie zezwolić aplikacji dokujania na utworzenie pliku s na hoście jako użytkownik hosta?
Jedynym rozwiązaniem można myślę teraz (Super hacky) ma się zmienić uprawnienia /etc/passwd
w obrazie Döcker być zapisywany w skali globalnej, a następnie dodać nową linię do tego pliku w czasie wykonywania przypisać nowy Para UID/GID do nazwy użytkownika.
OMG! Teraz mówisz, że to brzmi tak oczywiste! Myślę, że udostępnianie pliku hosta '/ etc/passwd' jest sposobem, w jaki pójdę. Dzięki! –
Przyznam ci nagrodę za 13 godzin, kiedy pozwoli mi –
Właściwie, myślę, że użyję twojej drugiej sugestii, ponieważ jest bardziej przenośna - np. będzie działać z systemami MacOS. –