docker: file yang dapat dieksekusi tidak ditemukan dalam $ PATH

216

Saya memiliki gambar buruh pelabuhan yang menginstal grunt, tetapi ketika saya mencoba menjalankannya, saya mendapatkan kesalahan:

Error response from daemon: Cannot start container foo_1: \
    exec: "grunt serve": executable file not found in $PATH

Jika saya menjalankan bash dalam mode interaktif, grunttersedia.

Apa yang saya lakukan salah?

Ini Dockerfile saya:

# https://registry.hub.docker.com/u/dockerfile/nodejs/ (builds on ubuntu:14.04)
FROM dockerfile/nodejs

MAINTAINER My Name, [email protected]

ENV HOME /home/web
WORKDIR /home/web/site

RUN useradd web -d /home/web -s /bin/bash -m

RUN npm install -g grunt-cli
RUN npm install -g bower

RUN chown -R web:web /home/web
USER web

RUN git clone https://github.com/repo/site /home/web/site

RUN npm install
RUN bower install --config.interactive=false --allow-root

ENV NODE_ENV development

# Port 9000 for server
# Port 35729 for livereload
EXPOSE 9000 35729
CMD ["grunt"]
Steve Lorimer
sumber
mungkin Anda mencoba membangun buruh pelabuhan menggunakan CMD grunt? Atau mungkin Anda mencoba untuk mengeksekusi perintah kasar dengan melewati path lengkap?
mgaido
@ mark91 tolong bisakah Anda menguraikan tentang apa yang Anda minta untuk dibangun kembali menggunakan CMD grunt?Maksud Anda drop the ["and "]?
Steve Lorimer
Hanya mencobanya - dan berhasil - terima kasih! Jadi untuk siapa pun yang datang, ganti CMD ["grunt"]keCMD grunt
Steve Lorimer
10
Ini karena jika Anda melakukannya, CMD ["grunt"]Anda menggunakan shell lain untuk menjalankan perintah, jadi di dalam shell itu $ PATH kemungkinan tidak akan disetel.
mgaido
Lihat juga stackoverflow.com/q/48001082/798677
Orang Brasil

Jawaban:

198

Ketika Anda menggunakan format exec untuk sebuah perintah (mis. CMD ["grunt"], Array JSON dengan tanda kutip ganda) itu akan dieksekusi tanpa shell. Ini berarti bahwa sebagian besar variabel lingkungan tidak akan ada.

Jika Anda menetapkan perintah sebagai string biasa (mis. CMD grunt) Maka string sesudahnya CMDakan dieksekusi bersama /bin/sh -c.

Info lebih lanjut tentang ini tersedia di bagian CMD dari referensi Dockerfile .

Kevan Ahlquist
sumber
2
Ini adalah tautan ke bagian CMD dari dokumen referensi docs.docker.com/engine/reference/builder/#cmd
Calvin
Maaf pertanyaan bodoh ini, tapi bagaimana Anda bisa menjalankan perintah linux tanpa shell? Apa yang setara dengan melakukan ini pada mesin linux (tidak menggunakan buruh pelabuhan)?
wisbucky
1
Untuk menjawab pertanyaan saya sendiri, ini mirip dengan melakukan sudo setatau (exec set). Itu akan gagal karena mereka menjalankan perintah tanpa shell (dan setshell builtin). Namun, sudo lsdan (exec ls)akan berfungsi karena lsini adalah file biner yang sebenarnya /bin/ls.
wisbucky
315

Ini adalah hasil pertama di google ketika saya menempelkan pesan kesalahan saya, dan itu karena argumen saya tidak sesuai.

Nama wadah harus setelah semua argumen.

Buruk:

docker run <container_name> -v $(pwd):/src -it

Baik:

docker run -v $(pwd):/src -it <container_name>
sarung
sumber
132
Jika Anda selalu membaca dokumentasi dengan seksama sebelum mulai membuat kode, Anda tidak akan pernah menyelesaikan apa pun. Ketika Anda membeli mobil baru Anda, apakah Anda membaca manual 200 halaman sebelum Anda membawanya pulang? Tidak. Dan ketika ada masalah dengan mobil Anda, apakah Anda google terlebih dahulu, atau apakah Anda mendapatkan manual? Ini benar-benar masuk akal, saya hanya bisa membayangkan semua orang yang merasa berguna tetapi belum mengklik tombol upvote! Apa yang agak tidak masuk akal adalah bahwa jawaban yang sama sekali tidak terkait ini adalah hasil google pertama untuk pesan kesalahan ini, atau bahwa buruh pelabuhan tidak intuitif dan tidak memaafkan. Bersulang.
sarink
8
Dalam banyak skrip urutan bendera tidak penting, jadi saya bisa melihat mengapa ini bisa terjadi pada siapa saja. Jawabannya cukup membantu. Tidak perlu dikatakan bahwa pesan kesalahan dari buruh pelabuhan tidak berguna sama sekali.
marios
9
Wow, saya akan berjuang untuk sementara waktu jika bukan karena jawaban ini. Mengapa UNIX belum memiliki parser argumen CLI standar, fleksibel dan kuat? ...
lleaff
1
Ini masalah bagi saya. Menempatkan nama wadah pada akhirnya sepertinya berhasil
Rob Segal
3
Saya disesatkan oleh jawaban yang diterima, ingin menulis sendiri, tetapi sepertinya sudah ada di sini. Jadi saya bisa memastikan bahwa ini menyelesaikan masalah ...
Arturas M
24

Saya menemukan masalah yang sama. Saya melakukan yang berikut:

docker run -ti devops -v /tmp:/tmp /bin/bash

Ketika saya mengubahnya ke

docker run -ti -v /tmp:/tmp devops /bin/bash

ini bekerja dengan baik.

keniee van
sumber
1
Itu berhasil untukku, kawan, Tapi aku tidak mengerti penggunaan di -vsini. -vadalah untuk mengikat mount volume (seperti yang dijelaskan dalam docker run --help | grep "\-v"), bagi saya, saya sudah menginstal /tmpdi File Sharing(pengaturan Docker), jadi mengapa saya harus menggunakannya lagi?
Ahmad
12

Ada beberapa kemungkinan alasan untuk kesalahan seperti ini.

Dalam kasus saya, itu karena file yang dapat dieksekusi ( docker-entrypoint.shdari blog Ghost Dockerfile ) tidak memiliki mode file yang dapat dieksekusi setelah saya mengunduhnya.

Larutan: chmod +x docker-entrypoint.sh

Ben Creasy
sumber
Ini adalah komentar yang mengarahkan saya ke jawaban yang benar. Saya harus menyalin file dan kemudian chmod itu.
melebihi dari
7

Wadah Docker mungkin dibuat tanpa shell (mis. Https://github.com/fluent/fluent-bit-docker-image/issues/19 ).

Dalam hal ini, Anda dapat menyalin-di shell yang dikompilasi secara statis dan menjalankannya, misalnya

docker create --name temp-busybox busybox:1.31.0
docker cp temp-busybox:/bin/busybox busybox
docker cp busybox mycontainerid:/busybox
docker exec -it mycontainerid /bin/busybox sh
Gajus
sumber
4

Untuk beberapa alasan, saya mendapatkan kesalahan itu kecuali jika saya menambahkan penjelas "bash". Bahkan menambahkan "#! / Bin / bash" ke bagian atas file entrypoint saya tidak membantu.

ENTRYPOINT [ "bash", "entrypoint.sh" ]
melampaui batas
sumber
@SteveLorimer, ya. Saya melakukan COPYdan kemudian RUN chmod +x /compile_nibbler.shsebelum panggilan entrypoint.
melampaui dari
1

Saya memiliki masalah yang sama, Setelah banyak googling, saya tidak dapat menemukan cara memperbaikinya.

Tiba-tiba saya menyadari kesalahan bodoh saya :)

Seperti disebutkan dalam dokumen , bagian terakhir docker runadalah perintah yang ingin Anda jalankan dan argumennya setelah memuat wadah.

BUKAN NAMA KONTAINER !!!

Itu kesalahan saya yang memalukan.

Di bawah ini saya memberi Anda gambar baris perintah saya untuk melihat apa yang telah saya lakukan salah.

Dan ini adalah perbaikan sebagaimana disebutkan dalam dokumen .

masukkan deskripsi gambar di sini

Parsa
sumber
-7

untuk membuatnya berfungsi, tambahkan referensi lunak ke / usr / bin:

ln -s $ (simpul mana) / usr / bin / simpul

ln -s $ (yang npm) / usr / bin / npm

vacavaca
sumber
1
Harap tambahkan deskripsi tentang bagaimana ini akan membantunya.
Mathews Sunny