Die Verwendung der RUN-Anweisung in einer Docker-Datei mit 'source' funktioniert nicht

274

Ich habe eine Docker-Datei, die ich zusammenstelle, um eine Vanille-Python-Umgebung zu installieren (in die ich eine App installieren werde, aber zu einem späteren Zeitpunkt).

FROM ubuntu:12.04

# required to build certain python libraries
RUN apt-get install python-dev -y

# install pip - canonical installation instructions from pip-installer.org
# http://www.pip-installer.org/en/latest/installing.html
ADD https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py /tmp/ez_setup.py
ADD https://raw.github.com/pypa/pip/master/contrib/get-pip.py /tmp/get-pip.py
RUN python /tmp/ez_setup.py
RUN python /tmp/get-pip.py
RUN pip install --upgrade pip 

# install and configure virtualenv
RUN pip install virtualenv 
RUN pip install virtualenvwrapper
ENV WORKON_HOME ~/.virtualenvs
RUN mkdir -p $WORKON_HOME
RUN source /usr/local/bin/virtualenvwrapper.sh

Der Build läuft bis zur letzten Zeile in Ordnung, wo ich die folgende Ausnahme bekomme:

[previous steps 1-9 removed for clarity]
...
Successfully installed virtualenvwrapper virtualenv-clone stevedore
Cleaning up...
 ---> 1fc253a8f860
Step 10 : ENV WORKON_HOME ~/.virtualenvs
 ---> Running in 8b0145d2c80d
 ---> 0f91a5d96013
Step 11 : RUN mkdir -p $WORKON_HOME
 ---> Running in 9d2552712ddf
 ---> 3a87364c7b45
Step 12 : RUN source /usr/local/bin/virtualenvwrapper.sh
 ---> Running in c13a187261ec
/bin/sh: 1: source: not found

Wenn ich lsin dieses Verzeichnis gehe (nur um zu testen, ob die vorherigen Schritte festgeschrieben wurden), kann ich sehen, dass die Dateien wie erwartet vorhanden sind:

$ docker run 3a87 ls /usr/local/bin
easy_install
easy_install-2.7
pip
pip-2.7
virtualenv
virtualenv-2.7
virtualenv-clone
virtualenvwrapper.sh
virtualenvwrapper_lazy.sh

Wenn ich versuche, nur den sourceBefehl auszuführen, wird der gleiche Fehler wie oben angezeigt. Wenn ich jedoch eine interaktive Shell-Sitzung starte, funktioniert die Quelle:

$ docker run 3a87 bash
source
bash: line 1: source: filename argument required
source: usage: source filename [arguments]

Ich kann das Skript von hier laufen, und dann glücklich Zugang workon, mkvirtualenvusw.

Ich habe ein bisschen gegraben, und anfangs sah es so aus, als ob das Problem im Unterschied zwischen bash als Ubuntu- Login-Shell und dash als Ubuntu- System-Shell liegen könnte . Dash den sourceBefehl nicht unterstützt .

Die Antwort darauf scheint jedoch zu sein '.' statt source, aber dies führt nur dazu, dass die Docker-Laufzeit mit einer Go-Panic-Ausnahme explodiert.

Was ist der beste Weg, um ein Shell-Skript über eine Dockerfile-RUN-Anweisung auszuführen, um dies zu umgehen (ich verwende das Standard-Basis-Image für Ubuntu 12.04 LTS).

Hugo Rodger-Brown
quelle
2
Also nicht "quellen", sondern nur den Befehl ausführen. Oder führen Sie das Shell-Skript speziell mit 'bash' aus.
Alister Bulman
Versuchte das - obwohl das Skript nicht fehlschlägt, bekomme ich keinen Zugriff auf die verschiedenen Befehle, die ich wollte. Dieses Problem ist das gleiche - github.com/dotcloud/docker/issues/2847
Hugo Rodger-Brown
2
Was, wenn man darüber nachdenkt, richtig ist. Virtualenvwrapper macht in einer Containerumgebung wahrscheinlich keinen Sinn. Ich werde es zurücksetzen und stattdessen 'native' virtualenv verwenden.
Hugo Rodger-Brown
1
Der grundlegendere Weg, dies zu erreichen, ist stackoverflow.com/questions/4732200/…
Gaurav Ojha
Versuchen SieCMD source activate django-py35
Belter

Antworten:

315

RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh"

Chobo
quelle
66
Eh? Wenn Sie ein Skript in einer Shell als Quelle verwenden, die nur für den Befehl vorhanden ist, kann es keine dauerhaften Auswirkungen auf zukünftige ausgeführte Befehle haben, vorausgesetzt, die Gesamtsumme seiner Aktion setzt Umgebungsvariablen. Also , warum würden Sie sourceüberhaupt, gegen nur bash /usr/local/bin/virtualenvwrapper.shin diesem Fall?
Charles Duffy
13
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh; my_command; my_command; my_command;"
Leo
28
Dies ist nicht korrekt, obwohl es funktioniert. Lesen Sie docs.docker.com/engine/reference/builder/#run und hören Sie nach dem zweiten Codebeispiel nicht auf. Lesen Sie den Hinweis: der unmittelbar folgt. Da dies /bin/sh -cdie Standard-Shell ist, wird diese "Shell-Form" von RUN in übersetzt RUN ["/bin/sh", "-c", "/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]. Sie sollten gehen Sie vor und nutzen die „exec Form“ RUN , so dass Sie die nehmen shsich wie soRUN ["/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]
Bruno Bronosky
8
Unter stackoverflow.com/a/45087082/117471 erfahren Sie , warum dies ein bashverschachteltes in einem erstellt shund daher vermieden werden sollte.
Bruno Bronosky
4
Eine viel bessere Antwort ist hier: stackoverflow.com/a/42216046/1663462
Chris Stryczynski
150

Ursprüngliche Antwort

FROM ubuntu:14.04
RUN rm /bin/sh && ln -s /bin/bash /bin/sh

Dies sollte für jedes Ubuntu-Docker-Basis-Image funktionieren. Im Allgemeinen füge ich diese Zeile für jede Docker-Datei hinzu, die ich schreibe.

Bearbeiten von einem betroffenen Zuschauer

Wenn Sie den Effekt "Verwenden bashstatt in der shgesamten Docker-Datei" erzielen möchten, ohne das Betriebssystem im Container zu verändern und möglicherweise zu beschädigen , können Sie Docker einfach Ihre Absicht mitteilen . Das geht so:

SHELL ["/bin/bash", "-c"]

* Der mögliche Schaden besteht darin, dass viele Skripte unter Linux (bei einer neuen Ubuntu-Installation werden grep -rHInE '/bin/sh' /über 2700 Ergebnisse zurückgegeben) eine vollständige POSIX-Shell bei erwarten /bin/sh. Die Bash-Shell ist nicht nur POSIX plus zusätzliche integrierte Funktionen. Es gibt integrierte Funktionen (und mehr), die sich völlig anders verhalten als die in POSIX. Ich unterstütze es VOLLSTÄNDIG, POSIX zu vermeiden (und den Irrtum, dass jedes Skript, das Sie nicht auf einer anderen Shell getestet haben, funktioniert, weil Sie glauben, Basmismen vermieden zu haben) und nur Bashism zu verwenden. Aber du machst das mit einem richtigen Schebang in deinem Drehbuch. Nicht durch Herausziehen der POSIX-Shell unter dem gesamten Betriebssystem. (Es sei denn, Sie haben Zeit, alle 2700 Plus-Skripte zu überprüfen, die mit Linux geliefert werden, sowie alle Skripte in den von Ihnen installierten Paketen.)

Weitere Details in dieser Antwort unten. https://stackoverflow.com/a/45087082/117471

Anubhav Sinha
quelle
18
Dies kann ein wenig vereinfacht werden:ln -snf /bin/bash /bin/sh
30.
2
@ user1442219 dies ersetzt Standardbefehlsinterpreter von shbisbash
Bhargav Nanekalva
27
ln -s /bin/bash /bin/shDas ist eine schreckliche Idee. Ubuntu Ziele / bin / sh aus einem Grund zu stürzen. dash ist eine vollständig posix-Shell, die um Größenordnungen schneller ist als bash. Durch das Verknüpfen von / bin / sh mit bash wird die Leistung Ihres Servers drastisch reduziert. Zitieren: wiki.ubuntu.com/DashAsBinSh
xero
7
Dies ist ein schmutziger Hack, keine Lösung. Wenn Ihr Skript von der shShell ausgeführt wird, Sie dies jedoch möchten bash, besteht die richtige Lösung darin, den shProzess entweder basheinmalig aufzurufen bash -c 'source /script.sh && …', oder Sie können sogar so weit gehen, Bashismen (wie source) vollständig zu vermeiden , und stattdessen Verwenden Sie immer nur gültige POSIX-Entsprechungen, z . /script.sh. (Achten Sie auf das Leerzeichen nach dem .!) Wenn Ihr Skript ausführbar ist (nicht nur beschaffbar), lassen Sie Ihr Skript niemals mit einem Schebang liegen, #!/bin/shwenn es nicht wirklich sh-kompatibel ist. Verwenden Sie #!/bin/bashstattdessen.
Mark G.
7
Und wie kann ich nun die ursprüngliche Antwort ablehnen und die Bearbeitung durch "einen Betroffenen" verbessern?
Slava
65

Die Standard-Shell für die RUNAnweisung ist ["/bin/sh", "-c"].

RUN "source file"      # translates to: RUN /bin/sh -c "source file"

Mit der SHELL-Anweisung können Sie die Standard-Shell für nachfolgende RUNAnweisungen in Dockerfile ändern:

SHELL ["/bin/bash", "-c"] 

Jetzt hat sich die Standard-Shell geändert und Sie müssen sie nicht in jeder RUN-Anweisung explizit definieren

RUN "source file"    # now translates to: RUN /bin/bash -c "source file"

Zusätzlicher Hinweis : Sie können auch eine --loginOption hinzufügen, mit der eine Anmeldeshell gestartet wird. Dies bedeutet, dass ~/.bachrczum Beispiel gelesen wird und Sie es nicht explizit vor Ihrem Befehl beziehen müssen

Ahmad Abdelghany
quelle
1
Toller --login
Hinweis
Durch die Nutzung SHELL ["/bin/bash", "-c", "-l"] ich weitere Aktualisierungen der .bashrc-Datei verwenden, wodurch ich problemlos asdf-Befehle ausführen konnte.
Rowinson Gallego
46

Ich hatte das gleiche Problem und um die Pip-Installation in virtualenv auszuführen, musste ich diesen Befehl verwenden:

RUN pip install virtualenv virtualenvwrapper
RUN mkdir -p /opt/virtualenvs
ENV WORKON_HOME /opt/virtualenvs
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh \
    && mkvirtualenv myapp \
    && workon myapp \
    && pip install -r /mycode/myapp/requirements.txt"

Ich hoffe, es hilft.

Andrea Grandi
quelle
Falls Sie von ROS-Antworten kamen, ja, das funktioniert. So etwas wie:RUN /bin/bash -c "source /opt/ros/melodic/setup.bash && \ cd /home && \ git clone https://angelos.p:[email protected]/inno/grpc-comms.git && \ cd grpc-comms && \ mkdir build && \ cd build && \ cmake .. && make"
angelos.p
44

Am einfachsten ist es, den Punktoperator anstelle der Quelle zu verwenden, die dem sh-Äquivalent der Bash entspricht source Befehl:

Anstatt:

RUN source /usr/local/bin/virtualenvwrapper.sh

Verwenden:

RUN . /usr/local/bin/virtualenvwrapper.sh
mixja
quelle
"source ist eine eingebaute Bourne-Shell und ein POSIX-Special" - ss64.com/bash/source.html linux.die.net/man/1/sh ... . / sourceakzeptiert auch Positionsparameter nach dem Dateinamen
Wes Turner
5
Dies funktioniert nicht, da jeder RUN-Befehl unabhängig arbeitet. Die Änderungen von sourceoder .gehen verloren, wenn der Befehl RUN beendet wird. Siehe: stackoverflow.com/a/40045930/19501
amit
26

Wenn Sie Docker 1.12 oder höher verwenden, verwenden Sie einfach SHELL !

Kurze Antwort:

Allgemeines:

SHELL ["/bin/bash", "-c"] 

für Python Vituralenv:

SHELL ["/bin/bash", "-c", "source /usr/local/bin/virtualenvwrapper.sh"]

Lange Antwort:

von https://docs.docker.com/engine/reference/builder/#/shell

SHELL ["executable", "parameters"]

Mit der SHELL-Anweisung kann die Standard-Shell, die für die Shell-Befehlsform verwendet wird, überschrieben werden. Die Standard-Shell unter Linux ist ["/ bin / sh", "-c"] und unter Windows ["cmd", "/ S", "/ C"]. Die SHELL-Anweisung muss in JSON-Form in einer Docker-Datei geschrieben sein.

Die SHELL-Anweisung ist besonders nützlich unter Windows, wo zwei häufig verwendete und recht unterschiedliche native Shells vorhanden sind: cmd und Powershell sowie alternative Shells, einschließlich sh.

Die SHELL-Anweisung kann mehrmals angezeigt werden. Jede SHELL-Anweisung überschreibt alle vorherigen SHELL-Anweisungen und wirkt sich auf alle nachfolgenden Anweisungen aus. Beispielsweise:

FROM microsoft/windowsservercore

# Executed as cmd /S /C echo default
RUN echo default

# Executed as cmd /S /C powershell -command Write-Host default
RUN powershell -command Write-Host default

# Executed as powershell -command Write-Host hello
SHELL ["powershell", "-command"]
RUN Write-Host hello

# Executed as cmd /S /C echo hello
SHELL ["cmd", "/S"", "/C"]
RUN echo hello

Die folgenden Anweisungen können von der SHELL-Anweisung beeinflusst werden, wenn die Shell-Form in einer Docker-Datei verwendet wird: RUN, CMD und ENTRYPOINT.

Das folgende Beispiel ist ein allgemeines Muster unter Windows, das mithilfe der SHELL-Anweisung optimiert werden kann:

...
RUN powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"
...

Der vom Docker aufgerufene Befehl lautet:

cmd /S /C powershell -command Execute-MyCmdlet -param1 "c:\foo.txt"

Dies ist aus zwei Gründen ineffizient. Erstens wird ein nicht notwendiger Befehlsprozessor cmd.exe (auch bekannt als Shell) aufgerufen. Zweitens erfordert jeder RUN-Befehl in der Shell-Form einen zusätzlichen Powershell-Befehl, der dem Befehl vorangestellt ist.

Um dies effizienter zu gestalten, kann einer von zwei Mechanismen eingesetzt werden. Eine besteht darin, die JSON-Form des RUN-Befehls zu verwenden, z.

...
RUN ["powershell", "-command", "Execute-MyCmdlet", "-param1 \"c:\\foo.txt\""]
...

Während das JSON-Formular eindeutig ist und nicht die nicht erforderliche cmd.exe verwendet, erfordert es mehr Ausführlichkeit durch doppelte Anführungszeichen und Escapezeichen. Der alternative Mechanismus besteht darin, die SHELL-Anweisung und das Shell-Formular zu verwenden, um Windows-Benutzern eine natürlichere Syntax zu bieten, insbesondere in Kombination mit der Escape-Parser-Direktive:

# escape=`

FROM microsoft/nanoserver
SHELL ["powershell","-command"]
RUN New-Item -ItemType Directory C:\Example
ADD Execute-MyCmdlet.ps1 c:\example\
RUN c:\example\Execute-MyCmdlet -sample 'hello world'

Ergebend:

PS E:\docker\build\shell> docker build -t shell .
Sending build context to Docker daemon 4.096 kB
Step 1/5 : FROM microsoft/nanoserver
 ---> 22738ff49c6d
Step 2/5 : SHELL powershell -command
 ---> Running in 6fcdb6855ae2
 ---> 6331462d4300
Removing intermediate container 6fcdb6855ae2
Step 3/5 : RUN New-Item -ItemType Directory C:\Example
 ---> Running in d0eef8386e97


    Directory: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       10/28/2016  11:26 AM                Example


 ---> 3f2fbf1395d9
Removing intermediate container d0eef8386e97
Step 4/5 : ADD Execute-MyCmdlet.ps1 c:\example\
 ---> a955b2621c31
Removing intermediate container b825593d39fc
Step 5/5 : RUN c:\example\Execute-MyCmdlet 'hello world'
 ---> Running in be6d8e63fe75
hello world
 ---> 8e559e9bf424
Removing intermediate container be6d8e63fe75
Successfully built 8e559e9bf424
PS E:\docker\build\shell>

Der SHELL-Befehl kann auch verwendet werden, um die Funktionsweise einer Shell zu ändern. Wenn Sie beispielsweise unter Windows SHELL cmd / S / C / V: EIN | AUS verwenden, kann die Semantik der verzögerten Erweiterung von Umgebungsvariablen geändert werden.

Der SHELL-Befehl kann auch unter Linux verwendet werden, wenn eine alternative Shell wie zsh, csh, tcsh und andere erforderlich ist.

Die SHELL-Funktion wurde in Docker 1.12 hinzugefügt.

Mithril
quelle
20

Aufbauend auf den Antworten auf dieser Seite möchte ich hinzufügen, dass Sie sich bewusst sein müssen, dass jede RUN-Anweisung unabhängig von den anderen mit ausgeführt wird /bin/sh -c und daher keine Umgebungsvariablen erhält, die normalerweise in Login-Shells verwendet werden.

Der beste Weg, den ich bisher gefunden habe, besteht darin, das Skript zu /etc/bash.bashrcjedem Befehl hinzuzufügen und ihn dann als Bash-Login aufzurufen.

RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc
RUN /bin/bash --login -c "your command"

Sie können beispielsweise virtualenvwrapper installieren und einrichten, die virtuelle Umgebung erstellen, sie aktivieren, wenn Sie ein Bash-Login verwenden, und dann Ihre Python-Module in dieser Umgebung installieren:

RUN pip install virtualenv virtualenvwrapper
RUN mkdir -p /opt/virtualenvs
ENV WORKON_HOME /opt/virtualenvs
RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc
RUN /bin/bash --login -c "mkvirtualenv myapp"
RUN echo "workon mpyapp" >> /etc/bash.bashrc
RUN /bin/bash --login -c "pip install ..."

Das Lesen des Handbuchs zu Bash-Startdateien hilft zu verstehen, was wann bezogen wird.

TomDotTom
quelle
1
Cool, basierend auf Ihrer Lösung, habe ich nur veranschaulicht: ADD env-file /etc/profile.d/installerenv.sh RUN /bin/bash --login -c 'env' RUN /bin/bash -c 'rm /etc/profile.d/installerenv.sh' Wenn der Anwendungsfall der Docker-Build-Perspektive mehr Injektionsumgebungsvariablen hinzufügt, wie ich es getan habe, würde ich empfehlen, einen Blick auf docs.docker.com/compose/yml zu werfen / # env-file auch.
daniel.kahlenberg
1
Ich glaube, das Problem dabei ist, dass Sie nicht die Ergebnisse jedes RUNBefehls zwischenspeichern, was bedeutet, dass Sie nicht viele Projektabhängigkeiten installieren und dann über den Quellcode kopieren und die Vorteile von nutzen können Zwischenschritt-Caching von Docker. Alle Projektabhängigkeiten werden jedes Mal neu installiert.
Erewok
Verwenden Sie /etc/bashrcfür Redhat, anstatt /etc/bash.bashrcwie oben erwähnt (für Ubuntu)
Jordan Gee
Ich habe /root/.bashrc für Centos verwendet.
schmudu
RUN echo "source /yourscript.bash" >> /etc/bash.bashrc macht den Trick. Wenn Sie Ros in Docker verwenden und die Umgebung einrichten möchten, sollten Sie dies tun
user27221
17

Nach https://docs.docker.com/engine/reference/builder/#run dem Standard [Linux] Shell für RUNist /bin/sh -c. Sie scheinen Bashismen zu erwarten, daher sollten Sie die "exec-Form" von verwenden RUN, um Ihre Shell anzugeben.

RUN ["/bin/bash", "-c", "source /usr/local/bin/virtualenvwrapper.sh"]

Andernfalls führt die Verwendung der "Shell-Form" von RUN und die Angabe einer anderen Shell zu verschachtelten Shells.

# don't do this...
RUN /bin/bash -c "source /usr/local/bin/virtualenvwrapper.sh"
# because it is the same as this...
RUN ["/bin/sh", "-c", "/bin/bash" "-c" "source /usr/local/bin/virtualenvwrapper.sh"]

Wenn Sie mehr als einen Befehl haben, der eine andere Shell benötigt, sollten Sie https://docs.docker.com/engine/reference/builder/#shell lesen und Ihre Standard-Shell ändern, indem Sie diesen vor Ihren RUN-Befehlen platzieren:

SHELL ["/bin/bash", "-c"]

Wenn Sie etwas in die .bashrcDatei des Root-Benutzers eingefügt haben, das Sie benötigen, können Sie das -lFlag zum SHELLoder hinzufügenRUN Befehl , um es zu einer Anmeldeshell zu machen und sicherzustellen, dass es bezogen wird.

Hinweis: Ich habe absichtlich die Tatsache ignoriert, dass es sinnlos ist, ein Skript als einzigen Befehl in einem RUN zu erstellen.

Bruno Bronosky
quelle
SHELL ["/bin/sh", "-c", "-l"]so dass es ~ / .bashrc usw. beschafft, falls Sie Umgebungseinstellungen vom
Basiscontainer haben
1
@MortenB, aber du hast angegeben (getippt?) /bin/sh das Problem der von Bash nicht löst. Außerdem ist docker buildes unwahrscheinlich, dass die .bashrc des Root-Benutzers etwas Nützliches enthält, das Sie benötigen. Aber wenn Sie dort früher in der Docker-Datei etwas eingefügt haben (wie vielleicht ein JAVA_HOME, dann ja. Ich werde in meiner Antwort eine Notiz darüber
einfügen
Entschuldigung für den Tippfehler, ich verwende pyenv, das ~ / .bashrc als Quelle angeben muss, um die Pfade für die richtige Python-Version in meinen Basis-Images festzulegen. Dadurch kann ich jede Linux-Basis verwenden und mit zwei Zeilen eine beliebige Version auf Python hinzufügen. Wie Python 3.7 auf Ubuntu16.04, wo Basis-Python 3.5.2 ist
MortenB
11

Laut Docker-Dokumentation

Um eine andere Shell als '/ bin / sh' zu verwenden, verwenden Sie das Exec-Formular, das in der gewünschten Shell übergeben wird. Zum Beispiel,

RUN ["/bin/bash", "-c", "echo hello"]

Siehe https://docs.docker.com/engine/reference/builder/#run

Gianluca Casati
quelle
Dies ist die IST-richtige Antwort. Der Autor der ausgewählten Antwort stackoverflow.com/a/25086628/117471 scheint nur das erste Beispiel in der Dokumentation gelesen zu haben, auf die Sie verlinken. Sie scheinen nicht den nächsten Absatz gelesen zu haben, den Sie zitiert haben.
Bruno Bronosky
4

Wenn Sie SHELLverfügbar sind, sollten Sie mit dieser Antwort fortfahren - verwenden Sie nicht die akzeptierte, da Sie gezwungen sind, den Rest der Docker-Datei gemäß diesem Kommentar in einen Befehl zu setzen .

Wenn Sie eine alte Docker-Version verwenden und keinen Zugriff darauf haben SHELL, funktioniert dies, solange Sie nichts von benötigen .bashrc(was in Docker-Dateien selten vorkommt):

ENTRYPOINT ["bash", "--rcfile", "/usr/local/bin/virtualenvwrapper.sh", "-ci"]

Beachten Sie, dass dies -ierforderlich ist, damit bash die RC-Datei überhaupt liest.

Mohan
quelle
3

Vielleicht möchten Sie laufen, um bash -vzu sehen, was bezogen wird.

Ich würde folgendes tun, anstatt mit Symlinks zu spielen:

RUN echo "source /usr/local/bin/virtualenvwrapper.sh" >> /etc/bash.bashrc

vimdude
quelle
3

Ich hatte auch Probleme beim Ausführen sourcein einer Docker-Datei

Dies funktioniert einwandfrei für die Erstellung von CentOS 6.6 Docker-Containern, hat jedoch Probleme in Debian-Containern verursacht

RUN cd ansible && source ./hacking/env-setup

So habe ich es angegangen, vielleicht nicht elegant, aber das hat bei mir funktioniert

RUN echo "source /ansible/hacking/env-setup" >> /tmp/setup
RUN /bin/bash -C "/tmp/setup"
RUN rm -f /tmp/setup
vikas027
quelle
2

Dies kann passieren, weil sourcees sich um eine integrierte Bash-Funktion handelt und nicht um eine Binärdatei im Dateisystem. Beabsichtigen Sie, dass das Skript, das Sie beziehen, den Container anschließend ändert?

Paul Morie
quelle
1
Das Skript aktualisiert zwar den Container - aber um ehrlich zu sein, habe ich versucht, etwas zu tun, das keinen Sinn ergab, also habe ich das Problem umgangen.
Hugo Rodger-Brown
1

Am Ende habe ich meine Env-Sachen reingelegt .profileund so SHELLetwas wie mutiert

SHELL ["/bin/bash", "-c", "-l"]

# Install ruby version specified in .ruby-version
RUN rvm install $(<.ruby-version)

# Install deps
RUN rvm use $(<.ruby-version) && gem install bundler && bundle install

CMD rvm use $(<.ruby-version) && ./myscript.rb
mattexx
quelle
3
"-c" muss das letzte Argument sein (bevor der Befehl ausgeführt werden soll)
Peterk
0

Wenn Sie nur versuchen, mit pip etwas in die virtuelle Umgebung zu installieren, können Sie die PATH-Umgebung so ändern, dass sie zuerst im bin-Ordner der virtuellen Umgebung angezeigt wird

ENV PATH="/path/to/venv/bin:${PATH}"

Dann finden alle pip installBefehle, die in der Docker-Datei folgen, zuerst / path / to / venv / bin / pip und verwenden diese, die in dieser virtuellen Umgebung und nicht in der Systempython installiert werden.

Shadfc
quelle