entri pelabuhan yang menjalankan skrip bash mendapat "izin ditolak"

122

Saya mencoba melakukan docker pada aplikasi node.js saya. Saat container dibuat, saya ingin menjalankan filegit clone dan kemudian memulai server node. Oleh karena itu saya menempatkan operasi ini dalam skrip .sh. Dan jalankan skrip sebagai satu perintah di ENTRYPOINT:

FROM ubuntu:14.04

RUN apt-get update && apt-get install -y build-essential libssl-dev gcc curl npm git

#install gcc 4.9
RUN apt-get install -y software-properties-common python-software-properties
RUN add-apt-repository -y ppa:ubuntu-toolchain-r/test
RUN apt-get update
RUN apt-get install -y libstdc++-4.9-dev

#install newst nodejs
RUN curl -sL https://deb.nodesource.com/setup_4.x | sudo -E bash -
RUN apt-get install -y nodejs

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

ADD package.json /usr/src/app/
RUN npm install

ADD docker-entrypoint.sh /usr/src/app/

EXPOSE 8080

ENTRYPOINT ["/usr/src/app/docker-entrypoint.sh"] 

Docker-entrypoint.sh saya terlihat seperti ini:

git clone git@<repo>.git
git add remote upstream git@<upstream_repo>.git

/usr/bin/node server.js

Setelah membangun gambar ini dan jalankan:

docker run --env NODE_ENV=development -p 8080:8080 -t -i <image>

Saya mendapatkan:

docker: Error response from daemon: oci runtime error: exec: "/usr/src/app/docker-entrypoint.sh": permission denied.

Saya masuk ke dalam wadah dan izin dari docker-entrypoint.sh adalah:

-rw-r--r-- 1 root root 292 Aug 10 18:41 docker-entrypoint.sh

tiga pertanyaan:

  1. Apakah skrip bash saya memiliki sintaks yang salah?

  2. Bagaimana cara mengubah izin file bash sebelum menambahkannya ke dalam gambar?

  3. Apa cara terbaik untuk menjalankan beberapa perintah git di entrypoint tanpa menggunakan skrip bash?

Terima kasih.

Calvin Hu
sumber
Kami perlu melihat izin file untuk dapat menjawab pertanyaan ini.
Charles Duffy
BTW, jika ini adalah skrip bash , bukan skrip sh , .shekstensi meninggalkan kesan yang menyesatkan tentang interpreter mana yang dapat menjalankannya. Anda mungkin mempertimbangkan untuk mengambil itu - tidak konvensional untuk perintah UNIX memiliki ekstensi (Anda tidak menjalankan ls.elf, misalnya).
Charles Duffy
Bisakah kita execmembuat cangkang seperti itu? bukankah itu membutuhkan bashawalan.
Jean-François Fabre
@ Jean-FrançoisFabre, apa sebenarnya yang Anda maksud dengan pertanyaan Anda? (Saya tidak mengerti apa artinya "exec a shell that way" - apa artinya "seperti itu" dalam konteks ini?)
Charles Duffy
2
Pertanyaan konyol, omong-omong - apakah izin skrip sudah benar sebelum Anda menambahkannya ke gambar?
Charles Duffy

Jawaban:

185
  1. "Izin ditolak" mencegah skrip Anda dipanggil sama sekali . Jadi, satu-satunya sintaks yang mungkin relevan adalah baris pertama ("shebang"), yang akan terlihat seperti #!/usr/bin/env bash, atau #!/bin/bash, atau serupa tergantung pada tata letak sistem file target Anda.

  2. Kemungkinan besar izin sistem file tidak disetel untuk mengizinkan eksekusi. Mungkin juga shebang mereferensikan sesuatu yang tidak dapat dieksekusi, tetapi kemungkinannya jauh lebih kecil.

  3. Diperdebatkan dengan kemudahan memperbaiki masalah sebelumnya.


Pembacaan sederhana dari

docker: Error response from daemon: oci runtime error: exec: "/usr/src/app/docker-entrypoint.sh": permission denied.

... adalah bahwa skrip tidak ditandai dapat dieksekusi.

RUN ["chmod", "+x", "/usr/src/app/docker-entrypoint.sh"]

akan membahas ini di dalam wadah. Sebagai alternatif, Anda dapat memastikan bahwa salinan lokal yang direferensikan oleh Dockerfile dapat dieksekusi , lalu gunakan COPY(yang secara eksplisit didokumentasikan untuk menyimpan metadata).

Charles Duffy
sumber
Saya pikir Anda benar. Saya harus menggunakan COPY sebagai gantinya. Tapi sepertinya saya masih perlu mengubah izin setelah MENGOPY skrip bash.
Calvin Hu
Saya memiliki file phar yang membuat skrip .bash berdasarkan perintah dan kemudian menghapusnya setelah selesai. Jadi kebutuhan untuk volume bersama untuk memiliki izin eksekusi adalah sesuatu yang masih saya perjuangkan.
raupie
@raupie, jika Anda ingin menjalankan script off titik dengan me-mount noexecbendera, jalankan bash yourscriptbukan ./yourscript.
Charles Duffy
1
Saya tidak mengerti, ketika saya menjalankan docker buildkontainer langsung berfungsi dengan baik. Tetapi ketika saya melakukannya docker run, itu membuat kesalahan seperti itu. Sepertinya wadah perantara ajaib yang saya punya.
Tiina
46

File yang dapat dieksekusi harus memiliki izin untuk mengeksekusi set sebelum Anda dapat mengeksekusinya.

Di komputer tempat Anda membuat image buruh pelabuhan (bukan di dalam image buruh pelabuhan itu sendiri) coba jalankan:

ls -la path/to/directory

Kolom pertama dari output untuk executable Anda (dalam hal ini docker-entrypoint.sh) harus memiliki bit yang dapat dieksekusi mengatur sesuatu seperti:

-rwxrwxr-x

Jika tidak, coba:

chmod +x docker-entrypoint.sh

dan kemudian buat citra buruh pelabuhan Anda lagi.

Docker menggunakan sistem filenya sendiri tetapi menyalin semuanya (termasuk bit izin) dari direktori sumber.

Sami Mulai
sumber
13
chmod +x docker-entrypoint.shdi tzhe host sebenarnya adalah solusi yang disarankan, karena jauh lebih sederhana daripada mengubah file Dockerfile.
jotrocken
17

Saya menghadapi masalah yang sama & itu diselesaikan oleh

ENTRYPOINT ["sh", "/docker-entrypoint.sh"]

Untuk Dockerfile di pertanyaan awal seharusnya seperti ini:

ENTRYPOINT ["sh", "/usr/src/app/docker-entrypoint.sh"]
Saurabhcdt
sumber
5
Ini adalah solusi, tapi bukan yang hebat - ini menafsirkan skrip dengan sh, mengabaikan spesifikasi penafsir shebang-nya; jadi jika itu menggunakan #!/bin/bash, mengatakan itu ingin diinterpretasikan dengan bash, itu akan diabaikan dan itu akan diinterpretasikan dengan sh, jadi melarang fitur bahasa seperti [[ ]], array, dll.
Charles Duffy
Saya telah menggunakan pendekatan Anda dan berhasil. Mungkin juga dos2unix berhasil
Wakan Tanka
1

Jika Anda tidak menggunakan DockerFile, Anda cukup menambahkan izin sebagai argumen baris perintah bash:

docker run -t <image>  /bin/bash -c "chmod +x /usr/src/app/docker-entrypoint.sh; /usr/src/app/docker-entrypoint.sh"
betontalpfa.dll
sumber
1

Ini adalah pertanyaan lama yang ditanyakan dua tahun sebelum jawaban saya, saya akan memposting apa yang berhasil untuk saya.

Di direktori kerja saya, saya memiliki dua file: Dockerfile & provision.sh

Dockerfile:

FROM centos:6.8

# put the script in the /root directory of the container
COPY provision.sh /root

# execute the script inside the container
RUN /root/provision.sh

EXPOSE 80

# Default command
CMD ["/bin/bash"]

provision.sh:

#!/usr/bin/env bash

yum upgrade

Saya dapat membuat file di kontainer buruh pelabuhan dapat dieksekusi dengan mengatur file di luar kontainer sebagai dapat dieksekusi chmod 700 provision.shkemudian berjalan docker build ..

BradChesney79
sumber