Come impostare gli alias bash per i contenitori Docker in Dockerfile?


87

Sono nuovo in Docker. Ho scoperto che possiamo impostare le variabili d'ambiente usando l'istruzione ENV nel Dockerfile. Ma come si impostano gli alias bash per i comandi lunghi in Dockerfile?


gli alias sono stati considerati essenzialmente deprecati per molto tempo. Usa una funzione. Non è più necessario utilizzare mai un alias. Come mai questi approcci dalla fine degli anni '80 persistono così a lungo?
William Pursell

19
Perché sono convenienti e semplici, ovviamente.
Arthur

13
@WilliamPursell Forse dovresti spiegare allora come usare le funzioni invece.
Eric Dela Cruz

2
Gli alias sono semplici, convenienti, fragili e soggetti a errori. Le funzioni sono altrettanto facili da usare, ma forniscono maggiore flessibilità e robustezza. Ci sono molte risorse disponibili su come usarli.
William Pursell

Risposte:


144

Fondamentalmente come fai sempre, aggiungendolo all'utente .bashrc:

FROM foo
RUN echo 'alias hi="echo hello"' >> ~/.bashrc

Come al solito questo funzionerà solo per le shell interattive:

docker build -t test .
docker run -it --rm --entrypoint /bin/bash test hi
/bin/bash: hi: No such file or directory
docker run -it --rm test bash
$ hi
hello

Per le shell non interattive dovresti creare un piccolo script e inserirlo nel tuo percorso, cioè:

RUN echo -e '#!/bin/bash\necho hello' > /usr/bin/hi && \
    chmod +x /usr/bin/hi

Se il tuo alias utilizza parametri (es. hi Jim-> hello Jim), aggiungi semplicemente "$@":

RUN echo -e '#!/bin/bash\necho hello "$@"' > /usr/bin/hi && \
    chmod +x /usr/bin/hi

Grazie per questo puoi fornire un esempio di shell non interattiva? Stavo cercando ENTRYPOINT e CMD per risolvere questo problema
c24b

5
L'alias Bash funziona solo nelle shell interattive. Basta creare un piccolo script di shell e inserire nel percorso, lo stesso effetto di un alias. Aggiornata la risposta con un semplice esempio.
Erik Dannenberg

1
Nota: da stackoverflow.com/a/8467449 dovresti piuttosto usare printf invece di echo per garantire un comportamento più coerente. Quindi printf '#! / Bin / bash \ necho hello'> / usr / bin / hi chmod + x / usr / bin / hi
barraq

2
Adoro l'idea dello script di shell. Stavo cercando di aggiungere alias, ma è molto meglio. Grazie.
Blizz

3
Dovresti usare "$ @" invece di $ * per l'escape di più argomenti. Vedi unix.stackexchange.com/questions/248464/…
gnou

14

Per creare un alias di un comando esistente, potresti anche utilizzare ln -s:

ln -s $(which <existing_command>) /usr/bin/<my_command>


7
Non lo chiamerei un alias .. è un soft link / symlink. La comodità degli alias è che puoi passare parametri al comando come alias ll='ls -lh'non è possibile con i collegamenti simbolici.
qwertz

3

Se vuoi usare gli alias solo in Dockerfile, ma non all'interno del container, il modo più breve è la ENVdichiarazione:

ENV update='apt-get update -qq'
ENV install='apt-get install -qq'

RUN $update && $install apt-utils \
    curl \
    gnupg \
    python3.6

E per l'utilizzo in container come già descritto:

 RUN printf '#!/bin/bash \n $(which apt-get) install -qq $@' > /usr/bin/install
 RUN chmod +x /usr/bin/install

Il più delle volte utilizzo gli alias solo in fase di costruzione e non entro nei contenitori, quindi il primo esempio è più veloce, più chiaro e più semplice per l'uso quotidiano.


2

L'ho appena aggiunto al mio app.dockerfile

# setup aliases
ADD ./bashrc_alias.sh /usr/sbin/bashrc_alias.sh
ADD ./initbash_profile.sh /usr/sbin/initbash_profile
RUN chmod +x /usr/sbin/initbash_profile
RUN /bin/bash -C "/usr/sbin/initbash_profile"

e all'interno del initbash_profile.shquale si aggiungono solo i miei alias personalizzati e non è necessario fornire il file .bashrc.

# add the bash aliases
cat /usr/sbin/bashrc_alias.sh >> ~/.bashrc

ha funzionato a meraviglia!

Un'altra opzione è usare semplicemente il "comando docker exec -it" dall'esterno del contenitore e usare semplicemente il tuo .bashrc o .bash_profile (come preferisci)

per esempio. docker exec -it docker_app_1 bash


1

Puoi usare l'entrypoint, ma non funzionerà per l'alias, nel tuo Dockerfile:

ADD dev/entrypoint.sh /opt/entrypoint.sh
ENTRYPOINT ["/opt/entrypoint.sh"]

Il tuo entrypoint.sh

#!/bin/bash
set -e

function dev_run()
{

}

export -f dev_run

exec "$@"

(Copia / incolla veloce, scusa)


Fai attenzione che alcune immagini Docker potrebbero già sovrascrivere il punto di ingresso predefinito (come l'immagine di base di phusion).
Thomas Decaux

1

Penso che il modo più semplice sarebbe montare un file nel tuo contenitore contenente i tuoi alias e quindi specificare dove bash dovrebbe trovarlo:

docker run \
    -it \
    --rm \
    -v ~/.bash_aliases:/tmp/.bash_aliases \
    [image] \
    /bin/bash --init-file /tmp/.bash_aliases

Utilizzo del campione:

user@cobalt:~$ echo 'alias what="echo it works"' > my_aliases
user@cobalt:~$ docker run -it --rm -v ~/my_aliases:/tmp/my_aliases ubuntu:18.04 /bin/bash --init-file /tmp/my_aliases
root@565e4a1bdcc0:/# alias
alias what='echo it works'
root@565e4a1bdcc0:/# what
it works

0

Ho utilizzato alcune delle soluzioni di cui sopra ma gli alias non vengono ancora riconosciuti.

Sto cercando di impostare gli alias e di utilizzarli sia nei passaggi successivi di Dockerfile che nel contenitore in fase di esecuzione.

RUN echo "alias model-downloader='python3 ${MODEL_DL_PATH}/downloader.py'" >> ~/.bash_aliases && \
    echo "alias model-converter='python3 ${MODEL_DL_PATH}/converter.py'" >> ~/.bash_aliases && \
    source ~/.bash_aliases

# Download the model
RUN model-downloader --name $MODEL_NAME -o $MODEL_DIR --precisions $MODEL_PRECISION;

La soluzione per me era utilizzare le variabili ENV che contenevano i percorsi delle cartelle e quindi aggiungere l'eseguibile esatto. Avrei potuto usare anche ARG, ma per più dei miei scenari avevo bisogno degli alias sia nella fase di compilazione che successivamente nel runtime.

Ha usato le variabili ENV insieme a uno script bash che viene eseguito una volta che le dipendenze sono state postate e imposta la sorgente bash, imposta alcune altre variabili env e consente di eseguire il pipe attraverso ulteriori comandi.


Ogni RUNistruzione viene eseguita in una nuova shell, quindi nel tuo esempio il file alias non viene più caricato quando provi a usare l'alias.
Erik Dannenberg

100% @ErikDannenberg grazie per il commento e anche per ricordarmi che devo pubblicare un aggiornamento a questo - ho scoperto una soluzione ed è molto simile a quello che hai suggerito.
alanionita

0

Ecco una funzione Bash per avere i tuoi alias in ogni contenitore che usi in modo interattivo.

ducker_it() {
    docker cp ~/bin/alias.sh "$1":/tmp
    docker exec -it "$1" /bin/bash -c "[[ ! -f /tmp/alias.sh.done ]] \
        && [[ -w /root/.bashrc ]] \
        && cat /tmp/alias.sh >> /root/.bashrc \
        && touch /tmp/alias.sh.done"
    docker exec -it "$1" /bin/bash
}

Passaggio richiesto prima:

grep ^alias ~/.zshrc > ~/bin/alias.sh

-1
  1. modifica questo file ~ / .bash_aliases vi ~/.bash_aliases
  2. fonte questo file ~ / .bash_aliases source ~/.bash_aliases
  3. fatto.

Questo va bene ogni volta che avvii il tuo container Docker, ma gli alias non rimarranno per la prossima volta. se non ti dispiace aggiungerli nuovamente ogni volta che questa soluzione va bene.
mikoop

Questa non è una risposta, ma beffa la persona che sta facendo la domanda.
bhuvin
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.