444 Stimmen

Die Verwendung der RUN-Anweisung in einem Dockerfile mit 'source' funktioniert nicht.

Ich habe ein Dockerfile, das ich zusammenstelle, um eine einfache Python-Umgebung zu installieren (in die ich später eine App installieren werde).

FROM ubuntu:12.04

# erforderlich zum Bauen bestimmter Python-Bibliotheken
RUN apt-get install python-dev -y

# installiere pip - kanonische Installationsanweisungen von 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 

# installiere und konfiguriere 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 OK, bis zur letzten Zeile, wo ich die folgende Ausnahme erhalte:

[vorherige Schritte 1-9 für Klarheit entfernt]
...
virtualenvwrapper virtualenv-clone stevedore erfolgreich installiert
Aufräumen...
 ---> 1fc253a8f860
Schritt 10 : ENV WORKON_HOME ~/.virtualenvs
 ---> In 8b0145d2c80d ausgeführt
 ---> 0f91a5d96013
Schritt 11 : RUN mkdir -p $WORKON_HOME
 ---> In 9d2552712ddf ausgeführt
 ---> 3a87364c7b45
Schritt 12 : RUN source /usr/local/bin/virtualenvwrapper.sh
 ---> In c13a187261ec ausgeführt
/bin/sh: 1: source: nicht gefunden

Wenn ich in dieses Verzeichnis ls mache (nur um zu testen, ob die vorherigen Schritte ausgeführt wurden), sehe ich, 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 source Befehl auszuführen, erhalte ich den gleichen 'nicht gefunden' Fehler wie oben. Wenn ich jedoch eine interaktive Shell-Sitzung mit RUN starte, funktioniert source:

$ docker run 3a87 bash
source
bash: Zeile 1: source: Dateiname Argument erforderlich
source: Verwendung: source Dateiname [Argumente]

Ich kann das Skript von hier aus ausführen und danach problemlos auf workon, mkvirtualenv usw. zugreifen.

Ich habe ein wenig recherchiert, und anfangs schien das Problem möglicherweise in der Unterscheidung zwischen bash als Ubuntu login shell und dash als Ubuntu system shell zu liegen, wobei dash den source Befehl nicht unterstützt.

Die Antwort darauf scheint jedoch zu sein, stattdessen '.' anstelle von source zu verwenden, doch das führt nur dazu, dass die Docker-Runtime mit einer go panic Ausnahme ausfällt.

Wie kann ein Shell-Skript aus einer Dockerfile RUN-Anweisung heraus ausgeführt werden, um dieses Problem zu umgehen (läuft auf dem Standard-Basisimage für Ubuntu 12.04 LTS)?

4voto

vimdude Punkte 4259

Sie möchten möglicherweise bash -v ausführen, um zu 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

4voto

nginx 74 Punkte 41

Dies ist meine Lösung auf "Ubuntu 20.04"

RUN apt -y update
RUN apt -y install curl
SHELL ["/bin/bash", "-c"]
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
RUN source /root/.bashrc
RUN bash -c ". /root/.nvm/nvm.sh && nvm install v16 && nvm alias default v16 && nvm use default"

2voto

Paul Morie Punkte 15078

Das könnte daran liegen, dass source in bash eingebaut ist, anstatt eine Binärdatei irgendwo im Dateisystem zu sein. Ist Ihre Absicht, dass das Skript, das Sie einbinden, den Container anschließend verändert?

1voto

Dockers SHELL-Befehl funktioniert immer noch im Jahr 2023!

Hier ist die Syntax, die in meinem Ubuntu-Container funktioniert hat:

RUN python -m venv .env # erstellt eine virtuelle Umgebung

SHELL ["/bin/bash", "-c"] # gibt Docker an, die Bash-Shell zu verwenden

RUN source .env/bin/activate # aktiviert Ihre virtuelle Umgebung

Referenziert von dieser früheren Antwort:

https://stackoverflow.com/a/25423366/10089368

Hier ist die DOCKER-Dokumentation dazu LOL

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

1voto

mattexx Punkte 6209

Am Ende habe ich meine Umgebungsvariablen in .profile platziert und SHELL etwas verändert, so etwas wie

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

# Installieren der in .ruby-version spezifizierten Ruby-Version
RUN rvm install $(<.ruby-version)

# Abhängigkeiten installieren
RUN rvm use $(<.ruby-version) && gem install bundler && bundle install

CMD rvm use $(<.ruby-version) && ./myscript.rb

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X