Bagaimana cara memulai wadah Docker yang berhenti dengan perintah yang berbeda?

251

Saya ingin memulai wadah Docker yang berhenti dengan perintah yang berbeda, karena perintah default macet - artinya saya tidak bisa memulai wadah dan kemudian menggunakan 'buruh pelabuhan exec'.

Pada dasarnya saya ingin memulai sebuah shell sehingga saya dapat memeriksa isi wadah.

Untungnya saya membuat wadah dengan opsi -itu!

aaa90210
sumber

Jawaban:

380

Temukan id kontainer Anda yang terhenti

docker ps -a

Komit wadah yang dihentikan:

Perintah ini menyimpan keadaan wadah yang dimodifikasi menjadi gambar baru user/test_image

docker commit $CONTAINER_ID user/test_image

Mulai / jalankan dengan titik masuk yang berbeda:

docker run -ti --entrypoint=sh user/test_image

Deskripsi argumen titik masuk: https://docs.docker.com/engine/reference/run/#/entrypoint-default-command-to-execute-at-runtime

catatan:

Langkah-langkah di atas hanya memulai wadah yang dihentikan dengan keadaan sistem file yang sama. Itu bagus untuk penyelidikan cepat. Tetapi variabel lingkungan, konfigurasi jaringan, volume terlampir dan staf lain tidak diwariskan, Anda harus menentukan semua argumen ini secara eksplisit.

Langkah-langkah untuk memulai wadah yang dihentikan telah dipinjam dari sini: (komentar terakhir) https://github.com/docker/docker/issues/18078

Dmitriusan
sumber
1
tidak, gambar hanya baca. Ini menyimpan keadaan wadah yang diubah menjadi gambar test_image baru
Dmitriusan
4
ini merindukan hampir semua konfigurasi tentang env, volume, UID, ... Yang memiliki kesamaan dengan container yang dihentikan adalah filesystem (yang mungkin cukup untuk beberapa)
Florian Klein
4
Akan lebih bagus jika saya entah bagaimana bisa mendapatkan lingkungan yang sama, konfigurasi jaringan, volume terlampir. Apakah mungkin untuk mengubah inspectoutput menjadi konfigurasi yang digunakan dengan proses selanjutnya?
Otheus
2
@ Webman, ya, tapi itu tidak berlaku untuk volume yang dipasang sebelum menghentikan sebuah wadah. Anda harus melampirkan volume yang sama secara eksplisit ketika Anda memulai wadah lain kali
Dmitriusan
1
@ EmreTapcı, saya pikir melakukan itu bertentangan dengan ideologi Docker. Kontainer dimaksudkan untuk menjadi entitas run-and-throw-away sing-use, berbeda dengan mesin virtual. Anda dapat mencoba mengikuti jawaban aaa90210 , tetapi ini akan menjadi peretasan.
Dmitriusan
126

Edit file ini (sesuai dengan wadah Anda yang dihentikan):

vi /var/lib/docker/containers/923...4f6/config.json

Ubah parameter "Path" untuk menunjuk pada perintah baru Anda, misalnya / bin / bash. Anda juga dapat mengatur parameter "Args" untuk meneruskan argumen ke perintah.

Mulai ulang layanan buruh pelabuhan (perhatikan ini akan menghentikan semua wadah yang berjalan):

service docker restart

Daftar wadah Anda dan pastikan perintah telah berubah:

docker ps -a

Mulai wadah dan pasangkan, Anda sekarang harus berada di shell Anda!

docker start -ai mad_brattain

Bekerja pada Fedora 22 menggunakan Docker 1.7.1.

CATATAN: Jika shell Anda tidak interaktif (misalnya Anda tidak membuat wadah asli dengan opsi -it), Anda dapat mengubah perintah menjadi "/ bin / sleep 600" atau "/ bin / tail -f / dev / null" untuk memberi Anda cukup waktu untuk melakukan "docker exec -it CONTID / bin / bash" sebagai cara lain untuk mendapatkan shell.

CATATAN2: Versi buruh pelabuhan yang lebih baru memiliki config.v2.json, di mana Anda harus mengubah Entri atau Cmd (terima kasih pengguna 60561).

aaa90210
sumber
44
mataku. mataku. Saya harap ini adalah permintaan fitur di suatu tempat untuk menangani ini dengan benar di Docker.
gertvdijk
2
@AlexeyStrakh Anda bisa mencoba menjalankan "/ usr / bin / sleep 600" dan kemudian melakukan "buruh pelabuhan exec -it / bin / bash" untuk mendapatkan shell. Meskipun saya tidak yakin bagaimana menempatkan parameter pada variabel Path itu. Kalau tidak, cobalah dan temukan perintah lain yang akan bertahan cukup lama bagi Anda untuk melakukan eksekutif, atau melihat jawaban dari Dmitriusan.
aaa90210
3
itulah satu-satunya jawaban yang benar-benar akurat untuk pertanyaan: semua proposisi lainnya menjalankan wadah "hampir sama", tetapi mereka lupa volume, env, UID, ...
Florian Klein
3
Dalam kasus saya / usr / bin / sleep tidak tersedia. Saya sukses dengan..."Path":"tail","Args":["-f","/dev/null"]...
nevrome
4
Memiliki versi buruh pelabuhan yang lebih baru config.v2.json, di mana Anda perlu mengubah salah satu Entrypointatau Cmd.
user60561
20

Tambahkan tanda centang di bagian atas skrip Entrypoint Anda

Docker benar-benar perlu mengimplementasikan ini sebagai fitur baru, tetapi inilah pilihan solusi lain untuk situasi di mana Anda memiliki Entrypoint yang berakhir setelah sukses atau gagal, yang dapat menyulitkan untuk debug.

Jika Anda belum memiliki skrip Entrypoint, buat skrip yang menjalankan perintah apa pun yang Anda perlukan untuk wadah Anda. Kemudian, di bagian atas file ini, tambahkan baris ini ke entrypoint.sh:

# Run once, hold otherwise
if [ -f "already_ran" ]; then
    echo "Already ran the Entrypoint once. Holding indefinitely for debugging."
    cat
fi
touch already_ran

# Do your main things down here

Untuk memastikan yang catmemegang koneksi, Anda mungkin perlu memberikan TTY. Saya menjalankan wadah dengan skrip Entrypoint saya seperti:

docker run -t --entrypoint entrypoint.sh image_name

Ini akan menyebabkan skrip dijalankan sekali, membuat file yang mengindikasikan skrip tersebut sudah berjalan (dalam sistem file virtual kontainer). Anda kemudian dapat memulai kembali wadah untuk melakukan debugging:

docker start container_name

Ketika Anda me-restart wadah, already_ranfile akan ditemukan, menyebabkan skrip Entrypoint berhenti cat(yang hanya menunggu selamanya untuk input yang tidak akan pernah datang, tetapi menjaga wadah tetap hidup). Anda kemudian dapat menjalankan bashsesi debugging :

docker exec -i container_name bash

Saat wadah berjalan, Anda juga dapat menghapus already_randan menjalankan entrypoint.shskrip secara manual untuk menjalankannya kembali, jika Anda perlu men-debug dengan cara itu.

Ethan T
sumber
3
Selain itu, Anda bisa membuat entrypoint berjalan /bin/shalih-alih cat- maka Anda selalu bisa masuk hanya dengan memulai ulang. Batuan solusi Anda!
Danny Dulai
4

Masalahku:

  • Saya memulai sebuah wadah dengan docker run <IMAGE_NAME>
  • Dan kemudian menambahkan beberapa file ke wadah ini
  • Kemudian saya menutup wadah dan mencoba memulainya lagi dengan perintah yang sama seperti di atas.
  • Tetapi ketika saya memeriksa file-file baru, mereka hilang
  • ketika saya berlari docker ps -asaya bisa melihat dua kontainer.
  • Itu berarti setiap kali saya menjalankan docker run <IMAGE_NAME>perintah, gambar baru mulai dibuat

Solusi: Untuk mengerjakan wadah yang sama yang Anda buat di tempat pertama jalankan ikuti langkah-langkah ini

  • docker ps untuk mendapatkan wadah dari wadah Anda
  • docker container start <CONTAINER_ID> untuk memulai wadah yang ada
  • Kemudian Anda dapat melanjutkan dari tempat Anda pergi. misalnyadocker exec -it <CONTAINER_ID> /bin/bash
  • Anda kemudian dapat memutuskan untuk membuat gambar baru darinya
Amit Dudhbade
sumber
Ini tidak menjawab pertanyaan. OP ingin tahu cara me-restart wadah tetapi dengan argumen yang berbeda dari yang digunakan didocker run <containerID>
CodeBlooded
2

Saya mengambil jawaban @ Dmitriusan dan membuatnya menjadi alias:

alias docker-run-prev-container = 'prev_container_id = "$ (buruh pelabuhan ps -aq | head -n1)" && buruh pelabuhan melakukan "$ prev_container_id" "prev_container / $ prev_container_id" && docker run -it --entrypoint = bash "prev_container / $ prev_container_id "'

Tambahkan ini ke ~/.bashrcfile alias Anda , dan Anda akan memiliki docker-run-prev-containeralias baru yang bagus yang akan menjatuhkan Anda ke shell di wadah sebelumnya.

Bermanfaat untuk debugging gagal docker builds.

Dean Sebaliknya
sumber
2

Ini bukan apa yang Anda minta, tetapi Anda dapat menggunakan docker exportwadah yang sudah berhenti jika yang Anda inginkan adalah memeriksa file.

mkdir $TARGET_DIR
docker export $CONTAINER_ID | tar -x -C $TARGET_DIR
Lars Christian Jensen
sumber
1

Tidak ditentukan apakah wadahnya keluar, hanya saja kode Anda mogok dan Anda perlu melihat apa yang terjadi di dalam wadah. Jika tidak keluar, berikut adalah solusi potensial lainnya.

Dapatkan id kontainer docker ps

docker exec -it 665b4a1e17b6 /bin/sh

Jika titik masuk diatur ke sesuatu yang bermasalah, itu juga dapat diganti seperti yang disarankan dalam jawaban Dmitriusan. Perlu juga dicatat bahwa Anda dapat menempel pada wadah berjalan dengan docker attach. Begitu banyak solusi solusi yang berbeda. Saya hanya tidak melihat perlunya komitmen pada gambar. Sepertinya tidak perlu.

Documents for Docker exec - https://docs.docker.com/engine/reference/commandline/exec/

Lampirkan Documents untuk Docker - https://docs.docker.com/engine/reference/commandline/attach/

deadbabykitten
sumber
-12

Saya sebenarnya tidak setuju dengan kedua jawaban ini. Jika Anda hanya ingin melihat apa yang ada di dalam wadah, maka Anda dapat menjalankan perintah ini untuk mendapatkan shell. Tidak perlu mengubah titik masuk sama sekali atau konfigurasi apa pun.

docker run -it <image_name> bash
deadbabykitten
sumber
12
Ini tidak berfungsi karena op bertanya tentang wadah, bukan gambar.
Peter Vrabel
Saya kira hak Anda tetapi tidak melihat alasan untuk melakukan itu. Anda dapat mengirimkan log ke stdout dan docker logs <container_id> --followakan memberikan apa yang Anda butuhkan. Alternatif lain adalah dengan menggunakan perintah di atas kemudian mulai layanan mogok pada gambar itu dengan perintah yang sama di dockerfile dan debug dari sana.
deadbabykitten
4
Perintah jalankan membuat wadah baru dari gambar. Itu tidak memulai wadah yang berhenti.
Waleed Abdulla
2
Ummm, .. bukankah maksud dari buruh pelabuhan adalah bahwa setiap gambar dapat diputar dengan cara yang persis sama? Ini meniadakan argumen Anda. Dia TIDAK PERLU memulai wadah yang berhenti. Wadah apa pun persis sama sehingga tidak masalah yang ia mulai atau hentikan. Dia hanya mencoba memeriksa isinya. Cara termudah untuk melakukannya adalah dengan mem-bash dan menjalankan perintah atau pipa keluaran dari perintah ke log. Kalian datang dengan solusi paling kompleks untuk masalah sederhana kadang-kadang.
deadbabykitten
-12
docker container start <CONTAINER_ID>
Oscar Calderón
sumber