Cách đặt bí danh bash cho vùng chứa docker trong Dockerfile?


85

Tôi là người mới đến docker. Tôi thấy rằng chúng ta có thể đặt các biến môi trường bằng cách sử dụng hướng dẫn ENV trong Dockerfile. Nhưng làm cách nào để đặt bí danh bash cho các lệnh dài trong Dockerfile?


bí danh đã được xem xét về cơ bản phản đối cho một rất thời gian dài. Sử dụng một chức năng. Không còn bất kỳ cần phải bao giờ sử dụng một bí danh. Làm thế nào mà những cách tiếp cận từ cuối những năm 80 này vẫn tồn tại lâu đến vậy?
William Pursell

19
Tất nhiên là vì chúng tiện lợi và đơn giản.
Arthur

13
@WilliamPursell Có lẽ bạn nên giải thích cách sử dụng các hàm thay thế.
Eric Dela Cruz,

2
Bí danh đơn giản, thuận tiện, dễ vỡ và dễ xảy ra lỗi. Các chức năng cũng dễ sử dụng nhưng mang lại sự linh hoạt và mạnh mẽ hơn. Có rất nhiều tài nguyên có sẵn về cách sử dụng chúng.
William Pursell,

Câu trả lời:


141

Về cơ bản như bạn vẫn làm, bằng cách thêm nó vào của người dùng .bashrc:

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

Như thường lệ, điều này sẽ chỉ hoạt động đối với các trình bao tương tác:

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

Đối với các trình bao không tương tác, bạn nên tạo một tập lệnh nhỏ và đặt nó vào đường dẫn của bạn, tức là:

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

Nếu bí danh của bạn sử dụng các tham số (tức là. hi Jim-> hello Jim), chỉ cần thêm "$@":

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

Cảm ơn vì điều này, bạn có thể cung cấp một ví dụ về trình bao không tương tác không? Tôi đang tìm kiếm EntryPoint và CMD để giải quyết này
c24b

5
Bí danh Bash chỉ hoạt động trong các trình bao tương tác. Chỉ cần tạo một tập lệnh shell nhỏ và đưa vào đường dẫn của bạn, hiệu ứng tương tự như một bí danh. Cập nhật câu trả lời bằng một ví dụ đơn giản.
Erik Dannenberg

1
Lưu ý: từ stackoverflow.com/a/8467449, bạn nên sử dụng printf thay vì echo để đảm bảo hành vi nhất quán hơn. Vì vậy, printf '#! / Bin / bash \ necho hello'> / usr / bin / hi chmod + x / usr / bin / hi
barraq

2
Yêu thích ý tưởng kịch bản shell. Đang tìm cách thêm bí danh nhưng điều này tốt hơn nhiều. Cảm ơn.
Bão tuyết

3
Bạn nên sử dụng "$ @" thay vì $ * để thoát nhiều đối số. Xem unix.stackexchange.com/questions/248464/…
gnou

14

Để tạo bí danh của một lệnh hiện có, cũng có thể sử dụng ln -s:

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


6
Tôi sẽ không gọi đây là một bí danh .. nó là một liên kết mềm / liên kết biểu tượng. Sự tiện lợi của bí danh là bạn có thể chuyển các tham số cho lệnh như alias ll='ls -lh'điều không thể thực hiện được với các liên kết tượng trưng.
qwertz

3

Nếu bạn chỉ muốn sử dụng bí danh trong Dockerfile, nhưng không phải bên trong vùng chứa thì cách ngắn nhất là ENVkhai báo:

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

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

Và để sử dụng trong vùng chứa theo cách như đã được mô tả:

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

Hầu hết thời gian tôi sử dụng bí danh chỉ trong giai đoạn xây dựng và không đi vào bên trong các thùng chứa, vì vậy ví dụ đầu tiên nhanh hơn, rõ ràng hơn và đơn giản hơn cho việc sử dụng hàng ngày.


2

Tôi vừa thêm cái này vào app.dockerfile của mình

# 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"

và bên trong initbash_profile.shchỉ thêm bí danh tùy chỉnh của tôi và không cần phải ghi nguồn tệp .bashrc.

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

làm việc một điều trị!

Một tùy chọn khác là chỉ sử dụng "lệnh docker -it" từ bên ngoài vùng chứa và chỉ sử dụng .bashrc hoặc .bash_profile của riêng bạn (tùy thích)

ví dụ. docker exec -it docker_app_1 bash


1

Bạn có thể sử dụng entrypoint, nhưng nó sẽ không hoạt động với bí danh, trong Dockerfile của bạn:

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

Của bạn entrypoint.sh

#!/bin/bash
set -e

function dev_run()
{

}

export -f dev_run

exec "$@"

(Sao chép / dán nhanh, xin lỗi)


Hãy chú ý rằng một số hình ảnh Docker đã có thể ghi đè điểm nhập mặc định (chẳng hạn như hình ảnh cơ sở phusion).
Thomas Decaux,

1

Tôi nghĩ cách dễ nhất là gắn một tệp vào vùng chứa chứa bí danh của bạn, sau đó chỉ định nơi bash sẽ tìm thấy nó:

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

Sử dụng mẫu:

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
  1. chỉnh sửa tệp này ~ / .bash_aliases vi ~/.bash_aliases
  2. nguồn tệp này ~ / .bash_aliases source ~/.bash_aliases
  3. làm xong.

Điều này là tốt mỗi khi bạn quay bộ chứa docker của mình nhưng bí danh sẽ không ở lại cho lần sau. nếu bạn không ngại thêm lại chúng mỗi lần giải pháp này là tốt.
mikoop

0

Đã sử dụng một số giải pháp ở trên nhưng các bí danh vẫn không được nhận dạng.

Tôi đang cố gắng đặt bí danh và sử dụng chúng cả trong các bước Dockerfile sau này và trong vùng chứa lúc chạy.

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;

Giải pháp cho tôi là sử dụng các biến ENV giữ các đường dẫn thư mục và sau đó thêm tệp thực thi chính xác. Tôi cũng có thể sử dụng ARG nhưng đối với nhiều trường hợp của tôi hơn, tôi cần bí danh trong cả giai đoạn xây dựng và sau đó trong thời gian chạy.

Đã sử dụng các biến ENV kết hợp với một tập lệnh bash chạy sau khi các phụ thuộc đã ponged và đặt nguồn bash, đặt thêm một số biến env và cho phép thêm các lệnh khác để chuyển qua.


Mọi RUNlệnh được thực thi trong một shell mới, vì vậy trong ví dụ của bạn, tệp bí danh không còn được tải khi bạn cố gắng sử dụng bí danh.
Erik Dannenberg

100% @ErikDannenberg cảm ơn bạn đã nhận xét và cũng đã nhắc tôi rằng tôi cần đăng bản cập nhật cho vấn đề này - Tôi đã phát hiện ra một giải pháp và nó rất giống như bạn đã đề xuất.
alanionita

0

Đây là một hàm Bash để có bí danh của bạn trong mọi vùng chứa mà bạn sử dụng một cách tương tác.

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
}

Bước bắt buộc trước:

grep ^alias ~/.zshrc > ~/bin/alias.sh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.