2017-02-17 35 views
12

Chcę utworzyć obraz Docker, który działa jako plik wykonywalny, dla którego użytkownik przekazuje token jako zmienną środowiskową. Plik wykonywalny ma polecenia podrzędne, które użytkownik powinien przekazać za pośrednictwem dokerów CMD (pomyśl o git z uwierzytelnianiem za pomocą Env). Jednak Docker nie dołącza CMD do punktu wejścia. Odpowiednia część mojego Dockerfile wygląda następująco:Kontener dokowany z rozszerzeniem zmiennoprzecinkowym i parametrami CMD

ENTRYPOINT ["/bin/sh", "-c", "/usr/bin/mycmd --token=$MY_TOKEN"] 
CMD ["pull", "stuff"] 

Więc jeśli ten pojemnik jest wykonywany bez nadpisania CMD i secret jako zmienną MY_TOKEN, spodziewam

mycmd --token=secret pull stuff 

być wykonywany. Jeśli użytkownik uruchomi kontener z pominięciem, np.

docker run -it -e MY_TOKEN=secret myimage push junk 

spodziewałbym

mycmd --token=secret push junk 

być wykonywany. Jak wspomniano powyżej, tylko wykonanie mycmd --token=secret zostaje wykonane, CMD jest ignorowana - bez względu na to, czy przesłonię ją podczas uruchamiania, czy ustawię w pliku Docker.

+1

czy wypróbowałeś 'dokowanie uruchom -to -e MY_TOKEN = secret myimage" push junk "'? – user2915097

+1

tak, to też nie działa. Nie wyjaśniłoby to również, dlaczego nie działa "bez" przesłonięcia CMD w uruchamianiu dockera – feob

+1

spróbuj zmienić swoją CMD w pliku Dockerfold za pomocą 'CMD [" sh "," -c "," pull "," stuff "]' , odtwórz obraz i ponownie przetestuj – user2915097

Odpowiedz

9

Przy składni /bin/sh -c "script" wszystko po argumencie -c staje się argumentem do skryptu. Można do nich dotrzeć z $0 i [email protected] jako część skryptu/bin/sh:

ENTRYPOINT ["/bin/sh", "-c", "exec /usr/bin/mycmd --token=$MY_TOKEN $0 [email protected]"] 
CMD ["pull", "stuff"] 

Uwaga, że ​​można również zmienić swój punktu wejścia być skryptem powłoki dodany do obrazu, który biegnie exec /usr/bin/mycmd --token=$MY_TOKEN "[email protected]" i wykonać ten skrypt przy użyciu składni exec docker:

ENTRYPOINT ["/entrypoint.sh"] 
+2

Zaktualizowałem moje polecenia, aby używać polecenia "exec" przed/usr/bin/mycmd, aby usunąć dodatkowy skrypt powłoki działający jako pid 1. – BMitch

+4

+1 za użycie '/ entrypoint.sh' i exec. Jedna rzecz do zapamiętania: powinieneś zacytować '$ @ ', np .:' exec/usr/bin/mycmd --token = $ MY_TOKEN "$ @" '. W przeciwnym razie możesz uzyskać dziwne zachowanie w przypadku napotkania spacji w argumentach. –

6

Zgodnie z określeniem in the docker documentation, określasz punkt początkowy, który wywołuje powłokę (a więc nie w postaci powłoki, ale exec). Parametry są przekazywane do powłoki (i dlatego są ignorowane); tylko polecenie w powłoce ma znaczenie. widać problem został rozwiązany po przełączeniu rozmowy punkt_wejścia do:

ENTRYPOINT ["usr/bin/mycmd", "--token=$MY_TOKEN"]

Wywoływanie powłoki w punkt_wejścia jest coś mocno zniechęcony, a dokładnie tylko użyteczne, gdy chcesz uniknąć użytkownikom obrazu dołączania parametrów niestandardowych twój punkt wejścia.

Do zobaczenia w interwebs! :)

+1

To nie działa, ponieważ w formularzu exec, żadne zmienne środowiskowe nie są rozszerzane: 'doker: odpowiedź błędu od demona: błąd wykonania w czasie OCi: container_linux.go: 247: uruchomienie procesu kontenera spowodowało" exec: \ "/ usr/bin/mycmd --token = $ MY_TOKEN \ ": stat/usr/bin/mycmd --token = $ MY_TOKEN: brak takiego pliku lub katalogu".' – feob

+0

Prawidłowy sposób to: ' ENTRYPOINT ["usr/bin/mycmd", "--token = $ MY_TOKEN"] ' –

+0

to ta sama linia, co w odpowiedzi Davida. Ponownie, to nie rozszerza zmiennej środowiskowej, ponieważ wykorzystuje formularz * exec *. – feob