Docker Compose menjaga container tetap berjalan


94

Saya ingin memulai layanan dengan docker-compose dan menjaga container tetap berjalan sehingga saya bisa mendapatkan alamat IP-nya melalui 'docker inspect'. Namun, kontainer selalu keluar segera setelah dinyalakan.

Saya mencoba menambahkan "perintah: [" tidur "," 60 "]" dan hal-hal lain ke docker-compose.yml tetapi setiap kali saya menambahkan baris dengan "perintah: ..." Saya tidak bisa memanggil "docker-compose up" karena saya akan mendapatkan pesan "Tidak dapat memulai penampung ..... Kesalahan sistem: karakter tidak valid 'k' mencari awal nilai"

Saya juga mencoba menambahkan "CMD sleep 60" dan yang lainnya ke Dockerfile itu sendiri tetapi perintah ini sepertinya tidak dijalankan.

Adakah cara mudah untuk menjaga agar wadah tetap hidup atau untuk memperbaiki salah satu masalah saya?

EDIT: Ini file Tulis yang ingin saya jalankan:

version: '2'
services:
  my-test:
    image: ubuntu
    command: bash -c "while true; do echo hello; sleep 2; done"

Ini berfungsi dengan baik Jika saya memulai ini dengan docker-compose di bawah OS X, tetapi jika saya mencoba hal yang sama di Ubuntu 16.04 itu memberi saya pesan kesalahan di atas.

Jika saya mencoba pendekatan dengan Dockerfile, Dockerfile akan terlihat seperti ini:

FROM ubuntu:latest
CMD ["sleep", "60"]

Yang sepertinya tidak melakukan apa-apa

EDIT 2: Saya harus mengoreksi diri sendiri, ternyata masalahnya sama dengan Dockerfile dan docker-compose.yml: Setiap kali saya menambahkan "CMD ..." ke Dockerfile ATAU tambahkan "perintah ..." ke file tulis, saya mendapatkan kesalahan di atas dengan karakter tidak valid. Jika saya menghapus kedua perintah, ini bekerja dengan sempurna.


1
Harap sertakan docker-compose.yml, Dockerfile, dan skrip apa pun yang Anda coba debug.
BMitch

Jawaban:


119

Agar container tetap berjalan saat Anda memulainya docker-compose, gunakan perintah berikut

command: tail -F anything

Jadi buruh pelabuhan-compose.yml Anda menjadi

version: '2'
services:
  my-test:
    image: ubuntu
    command: tail -F anything

dan Anda dapat menjalankan shell untuk masuk ke dalam container menggunakan perintah berikut

docker exec -i -t composename_my-test_1 bash

di mana composenamenama yang docker-composeada di awal penampung Anda.


1
Bagaimana Anda menghentikan wadah setelah selesai? Apakah ada jenis perintah Ctrl + C, Ctrl + Z? Sekarang saya harus menutup terminal untuk keluar.
mac10688

Jika Anda berada di dalam container, Anda dapat mengetik exituntuk kembali ke mesin host Anda. Jika Anda menggunakan host Anda, maka Anda dapat menghentikan container menggunakan Docker ( docker stop composename_my-test_1) atau Docker Compose ( docker-compose stop).
Nick Settje

2
@ Alexis.Rolland Jika Anda ingin mengajukan pertanyaan SO baru dan berbagi lebih banyak detail, saya akan dengan senang hati melihatnya. Dugaan saya adalah bahwa kesalahan Anda ada hubungannya dengan internal salah satu wadah Anda, yang bertentangan dengan masalah dengan Docker atau sistem operasi host Anda.
Nick Settje

1
@ mac10688 jika tidak ada prompt dalam sesi penampung terlampir Anda, maka coba ctrl-d untuk melepaskan
Stark

5
/dev/nullakan lebih baik di tempat untuk anythingperintah ekor ref. stackoverflow.com/a/48732671/248616
Nam G VU

80

Anda dapat menggunakan ttyopsi konfigurasi.

version: '3'

services:
  app:
    image: node:8
    tty: true           # <-- This option

Catatan: Jika Anda menggunakan Dockerfile untuk image dan CMDdi Dockerfile, opsi ini tidak akan berfungsi; namun, Anda dapat menggunakan entrypointopsi di file compose yang membersihkan CMDdari Dockerfile.


7
Ini berfungsi, dan tampaknya kurang hacky daripada tail -f /dev/null. Dengan ini, saya dapat menjalankan lingkungan dev dalam container dengan database postgres yang terpasang melalui docker-compose updan menjalankan shell melalui terminal lain menggunakan docker exec.
Psiloc

1
Sementara saat ini TIDAK terdokumentasi dengan baik. Ini adalah opsi resmi yang akan mencapai efek yang sama seperti tail -f /dev/nullatau tail -f anything, lihat di sini: docs.docker.com/compose/compose-file
b01

2
@ABMRuman & Psiloc, Ini bekerja hanya jika Anda tidak menggunakan "perintah" di file docker-compose.yml. Saat menggunakan "perintah", Anda memerlukan peretasan lain - karenanya peretasan tail -F sangat cocok di sini.
asafel

Ini harus menjadi jawaban terbaik jika Anda menggunakan entrypoint di dockerfile.
DDKV587

53

Berdasarkan komentar dari Gaanub di Gub, 26 Agustus 2015 , seseorang dapat menggunakan tail -f /dev/nulldalam pembuatan galangan untuk menjaga agar kontainer tetap berjalan.

contoh docker-compose.yml

version: '3'
services:
  some-app:
    command: tail -f /dev/null

Mengapa perintah ini?

Satu-satunya alasan untuk memilih opsi ini adalah karena opsi ini mendapat banyak jempol di GitHub, tetapi jawaban dengan suara terbanyak tidak berarti ini adalah jawaban terbaik. Alasan kedua adalah alasan pragmatis karena masalah harus diselesaikan secepat mungkin karena tenggat waktu.


2
mengapa tepatnya perintah ini? Apa yang membuatnya lebih baik dari yang lain? Dalam kasus saya, baru memulai pesta juga berhasil ...
N4ppeL

@ N4ppeL Pertanyaan bagus. Satu-satunya alasan saya memilih opsi ini adalah karena opsi ini mendapat banyak jempol di github, tetapi jawaban yang dipilih terbanyak tidak berarti bahwa itu adalah jawaban terbaik. Alasan kedua adalah alasan pragmatis karena saya harus menyelesaikan masalah ini secepat mungkin karena tenggat waktu.
030

17
  • Buat file bernama docker-compose.yml
  • Tambahkan berikut ini ke file
version: "3"

services:
  ubuntu:
    image: ubuntu:latest
    tty: true
  • Tetap di direktori yang sama, jalankan docker-compose up -ddari terminal
  • Jalankan docker psuntuk mendapatkan id atau nama penampung
  • Kamu bisa lari docker inspect $container_id
  • Anda dapat memasuki wadah dan menjalankan bash shell docker-compose exec ubuntu /bin/bashataudocker-compose exec ubuntu /bin/sh
  • Setelah selesai, pastikan Anda berada di luar wadah dan jalankan docker-compose down

Berikut ini skrip bash kecil ( my-docker-shell.sh) untuk membuat file penulisan buruh pelabuhan, menjalankan penampung, masuk ke penampung dan kemudian membersihkan penampung buruh pelabuhan dan file tulis buruh pelabuhan saat Anda keluar.

#!/bin/bash

cat << 'EOF' > ./docker-compose.yml
---

version: "3"

services:
  ubuntu:
    image: ubuntu:latest
    command: /bin/bash
    # tty: true

...
EOF

printf "Now entering the container...\n"
docker-compose run ubuntu bash
docker-compose down

rm -v ./docker-compose.yml

1
Meskipun ini bukan jawaban sebenarnya untuk pertanyaan itu, saya merasa itu sangat berharga! Saya melangkah lebih jauh untuk menggunakan fungsi bashrc global untuk pendekatan ini: gist.github.com/loopmode/4d59a4e9a0a2ffacaec2dd14db4ae8bd
loopmode

8

Di Dockerfile Anda dapat menggunakan perintah:

{CMD sleep infinity}

2

Seperti yang dinyatakan oleh pemberi komentar, kami harus melihat Dockerfile yang dimaksud untuk memberi Anda jawaban lengkap, tetapi ini adalah kesalahan yang sangat umum. Saya dapat menjamin cukup banyak bahwa perintah yang Anda coba jalankan memulai proses latar belakang. Ini mungkin perintah yang Anda jalankan dalam situasi non-Docker, tetapi itu adalah hal yang salah untuk dilakukan di Dockerfile. Misalnya, jika apa yang Anda jalankan biasanya ditetapkan sebagai layanan sistem, Anda mungkin menggunakan sesuatu seperti "systemctl start". Itu akan memulai proses di latar belakang, yang tidak akan berfungsi. Anda harus menjalankan proses di latar depan, sehingga seluruh proses akan diblokir.


0

Hanya catatan singkat

Saya telah menguji satu gambar berdasarkan golang, jadi ketika saya menelepon di docker-compose downsini apa yang saya dapatkan:

version: "3.1"
...
command: tail -f /dev/null   # stopping container takes about 10 sec.
tty: true                    # stopping container takes about 2 sec.

Info sistem saya:

Ubuntu 18.04.4 LTS (64-bit)
Docker version 19.03.6, build 369ce74a3c
docker-compose version 1.26.0, build d4451659

-3

Oke saya menemukan kesalahan saya. Di Dockerfile untuk gambar yang digunakan untuk menulis, saya menentukan bahwa gambar dasar harus ubuntu: terbaru, tetapi saya sebelumnya membuat gambar yang disebut ubuntu sendiri dan gambar itu tidak berfungsi. Jadi saya tidak menggunakan gambar ubuntu asli melainkan versi rusak dari gambar saya sendiri yang juga disebut ubuntu.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.