Compose: Jalankan perintah setelah dijalankan

Dibuat pada 5 Agu 2015  ·  131Komentar  ·  Sumber: docker/compose

Hai,

Akan sangat membantu jika memiliki sesuatu seperti "onrun" di YAML agar dapat menjalankan perintah setelah dijalankan. Mirip dengan https://github.com/docker/docker/issues/8860

mongodb:
    image: mongo:3.0.2
    hostname: myhostname
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 
    onrun:
        - mongodump --host db2dump.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

Setelah mongodb mulai, Ini akan membuang db2dump.domain.lan dan mengembalikannya.

Ketika saya akan berhenti dan kemudian memulai penampung, bagian onrun tidak akan dijalankan untuk menjaga idempotensi.

EDIT 15 Juni 2020

5 tahun kemudian, Compose tidak ingin spesifikasi "standarisasi",
silakan periksa https://github.com/compose-spec/compose-spec/issues/84

Komentar yang paling membantu

Jadi, untuk mengelola buruh pelabuhan saya, Anda menyarankan saya untuk menggunakan Script atau Makefile. Jadi mengapa menulis dibuat
? Kita bisa mengatur, menskalakan kontainer dll dengan skrip || dockerfile?

Ok, saya ambil contoh ini, itulah yang saya gunakan untuk menerapkan lingkungan pengujian aplikasi saya dalam proses CI.

rabbitmq:
    image: rabbitmq:3.5.1-management
    environment:
        RABBITMQ_NODENAME: rabbit
    hostname: rabbitmq
    domainname: domain.lan
    volumes:
        - /data/rabbitmq/db:/var/lib/rabbitmq
    ports:
        - "5672:5672" 
        - "15672:15672"
        - "25672:25672"
        - "4369:4369"

mongodb:
    image: mongo:3.0.2
    hostname: mongo
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 

appmaster:
    image: appmaster
    hostname: master
    domainname: domain.lan
    environment:
        ...
    ports:
        - "80:80" 
        - "8080:8080"
    links:
        - mongodb
        - rabbitmq

celery:
    image: celery
    hostname: celery
    domainname: domain.lan
    environment:
        ...
    links:
        - rabbitmq

Setelah penampung dimulai, saya harus menyediakan mongodb, mengelola antrian dan akun di rabbitmq

Apa yang saya lakukan hari ini adalah naskah dengan:

#!/bin/bash
PROJECT=appmaster
docker-compose -f appmaster.yml -p appmaster up -d
docker exec appmaster_rabbitmq_1 rabbitmqctl add_user user password
docker exec appmaster_rabbitmq_1 rabbitmqctl add_vhost rabbitmq.domain.lan
docker exec appmaster_rabbitmq_1 rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"
docker exec appmaster_mongodb_1 mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
docker exec appmaster_mongodb_1 mongorestore -d database /data/mongodb/dumps/latest/database

Dengan instruksi onrun saya bisa langsung menghasilkan docker-compose -f appmaster.yml -p appmaster up -d
dan file yml menjadi lebih mudah dibaca

rabbitmq:
    ...
    onrun:
        - rabbitmqctl add_user user password
        - rabbitmqctl add_vhost rabbitmq.domain.lan
        - rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"

mongodb:
    ...
    onrun:
        - mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

Semua 131 komentar

Saya pikir ini harus menjadi langkah-langkah di Dockerfile

FROM mongo:3.0.2
ADD data/mongodb/dumps/latest /data/mongodb/dumps/latest
RUN mongorestore -d database /data/mongodb/dumps/latest/database

Dengan cara itu Anda juga mendapatkannya dalam cache saat Anda membangun kembali.

Terima kasih @dnephin.
Tentu saja saya bisa membuat Dockerfile dan menggunakannya di build alih-alih image, atau saya bisa menggunakan docker exec.
MongoDB hanyalah sebuah contoh, Anda dapat memiliki contoh ini dengan mysql dan pembuatan akun, atau dengan rabbitmq dan pembuatan antrian, dll.

onrun akan memberikan fleksibilitas pada orkestrasi penulisan, penulisan akan membaca daftar onrun dan menghasilkan docker exec pada setiap item.

Intinya adalah menempatkan perintah ke docker exec di docker-compose.yml tidak diperlukan saat Anda dapat melakukannya di Dockerfile atau di skrip startup penampung, keduanya juga akan membuat container Anda lebih berguna saat _not_ dijalankan dengan Tulis.

Atau, mulai aplikasi Anda dengan skrip shell atau Makefile yang menjalankan perintah docker dan docker-compose .

Fungsionalitasnya tidak layak ditambahkan ke Tulis kecuali jika itu akan menambah nilai signifikan untuk melakukan salah satu dari itu, dan saya pikir itu tidak akan terjadi untuk kasus penggunaan yang Anda kutip.

Jadi, untuk mengelola buruh pelabuhan saya, Anda menyarankan saya untuk menggunakan Script atau Makefile. Jadi mengapa menulis dibuat
? Kita bisa mengatur, menskalakan kontainer dll dengan skrip || dockerfile?

Ok, saya ambil contoh ini, itulah yang saya gunakan untuk menerapkan lingkungan pengujian aplikasi saya dalam proses CI.

rabbitmq:
    image: rabbitmq:3.5.1-management
    environment:
        RABBITMQ_NODENAME: rabbit
    hostname: rabbitmq
    domainname: domain.lan
    volumes:
        - /data/rabbitmq/db:/var/lib/rabbitmq
    ports:
        - "5672:5672" 
        - "15672:15672"
        - "25672:25672"
        - "4369:4369"

mongodb:
    image: mongo:3.0.2
    hostname: mongo
    domainname: domain.lan
    volumes:
        - /data/mongodb:/data
    ports:
        - "27017:27017" 

appmaster:
    image: appmaster
    hostname: master
    domainname: domain.lan
    environment:
        ...
    ports:
        - "80:80" 
        - "8080:8080"
    links:
        - mongodb
        - rabbitmq

celery:
    image: celery
    hostname: celery
    domainname: domain.lan
    environment:
        ...
    links:
        - rabbitmq

Setelah penampung dimulai, saya harus menyediakan mongodb, mengelola antrian dan akun di rabbitmq

Apa yang saya lakukan hari ini adalah naskah dengan:

#!/bin/bash
PROJECT=appmaster
docker-compose -f appmaster.yml -p appmaster up -d
docker exec appmaster_rabbitmq_1 rabbitmqctl add_user user password
docker exec appmaster_rabbitmq_1 rabbitmqctl add_vhost rabbitmq.domain.lan
docker exec appmaster_rabbitmq_1 rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"
docker exec appmaster_mongodb_1 mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
docker exec appmaster_mongodb_1 mongorestore -d database /data/mongodb/dumps/latest/database

Dengan instruksi onrun saya bisa langsung menghasilkan docker-compose -f appmaster.yml -p appmaster up -d
dan file yml menjadi lebih mudah dibaca

rabbitmq:
    ...
    onrun:
        - rabbitmqctl add_user user password
        - rabbitmqctl add_vhost rabbitmq.domain.lan
        - rabbitmqctl set_permissions -p rabbitmq.domain.lan password ".*" ".*" ".*"

mongodb:
    ...
    onrun:
        - mongodump --host mongo-prd.domain.lan --port 27017 --out /data/mongodb/dumps/latest
        - mongorestore -d database /data/mongodb/dumps/latest/database

Ini akan lebih berguna dan menyelesaikan kasus penggunaan.

: +1:

Ini akan membuat penggunaan docker-compose lebih layak untuk pengujian yang terjaga keamanannya sebagai bagian dari pipeline CD

: +1:

Ini adalah duplikat dari # 877, # 1341, # 468 (dan beberapa lainnya).

Saya pikir cara yang tepat untuk mendukung ini adalah # 1510 dan mengizinkan alat eksternal untuk melakukan operasi ketika Anda mencapai acara yang Anda inginkan.

Menutup sebagai duplikat

Ini akan sangat berguna. Saya tidak mengerti argumen "oh, Anda bisa melakukan ini dengan skrip bash". Tentu saja kita bisa melakukannya dengan skrip bash. Saya juga bisa melakukan semua yang dilakukan Docker-compose dengan skrip bash. Tetapi intinya adalah ada satu file YAML yang mengontrol lingkungan pengujian Anda dan dapat diputar dengan perintah docker-compose up .

Ini bukan tugas Compose untuk melakukan _everything_ yang dapat dilakukan dengan skrip shell atau Makefile - kita harus menarik garis di suatu tempat untuk mencapai keseimbangan antara kegunaan dan menghindari pembengkakan.

Selain itu, satu properti penting dari file Compose adalah file ini cukup portabel di seluruh mesin - bahkan mesin Mac, Linux, dan Windows. Jika kita mengizinkan orang untuk meletakkan perintah shell sewenang-wenang di file Tulis, mereka akan menjadi jauh lebih tidak portabel.

@aanand Agar adil, dapat mengeksekusi docker exec tidak secara otomatis menyiratkan ketidakcocokan x-plat.

Maaf - Saya salah membaca masalah ini sebagai tentang menjalankan perintah pada mesin host. Tetap saja, poin pertama saya tetap ada.

Saya mengerti maksud Anda @aanand. Itu tidak tampak di luar jangkauan saya, karena sudah docker-compose melakukan banyak hal yang sama seperti yang sudah dilakukan oleh mesin docker biasa, seperti command , expose , ports , build , dll. Menambahkan fungsionalitas exec akan menambah daya ke docker-compose untuk menjadikannya toko serba ada yang benar untuk pengaturan up lingkungan dev.

@aandan masalah utama untuk banyak devs dan pipeline CI adalah memiliki data yang sangat dekat dengan env produksi. Seperti sampah dari DB. Saya membuat tiket ini 1 tahun yang lalu dan tidak ada yang bergerak dalam penulisan buruh pelabuhan.

Jadi Anda menyarankan Makefile atau Bashcript hanya untuk menjalankan beberapa exec https://github.com/docker/compose/issues/1809#issuecomment -128073224

Apa yang awalnya saya sarankan adalah onrun (atau oncreate) yang menjaga idempotensi. Jalankan saja di awal pertama. Jika wadah dihentikan atau dihentikan sementara, permulaan baru tidak akan berjalan onrun (atau oncreate)

Akhirnya, di repositori git saya, saya akan memiliki file compose, dockerfile dan makefile dengan manajemen idempotensi (mungkin makefile bisa membuat statefile). Jenius!

Ada perbedaan besar antara command , expose , dll dan exec . Grup pertama adalah opsi kontainer, exec adalah titik akhir perintah / api. Ini adalah fungsi terpisah, bukan opsi untuk membuat fungsi wadah.

Ada beberapa cara untuk melakukannya dengan Compose (https://github.com/docker/compose/issues/1809#issuecomment-128059030). onrun sudah ada. Itu command .

Mengenai masalah spesifik dumping atau memuat data dari database, itu lebih merupakan jenis tugas "alur kerja" atau "otomatisasi build", yang umumnya dilakukan di Makefile. Saya telah membuat prototipe alat untuk kasus penggunaan yang disebut dobi , yang menjalankan semua tugas dalam kontainer. Ini juga terintegrasi dengan sangat baik dengan Compose. Anda mungkin tertarik untuk mencobanya jika Anda tidak senang dengan Makefiles. Saya sedang mengerjakan contoh kasus penggunaan init / load database.

@dnephin onrun bukanlah command karena Anda melewatkan idempotensi.

Bayangkan. create pada pembuatan kontainer dan tidak akan pernah dieksekusi lagi (dump & restore).

exec:
    create:
        - echo baby
    destroy:
        - echo keny
    start:
        - echo start
    stop:
        - echo bye

Jika Anda membutuhkan lebih banyak contoh:

Terima kasih untuk dobi, tetapi jika Anda perlu membuat alat untuk meningkatkan penulisan, tulis itu buruk dan lebih baik menggunakan alat yang lebih kuat.

tetapi jika Anda perlu membuat alat untuk menyempurnakan penulisan, tulis itu buruk dan lebih baik menggunakan alat yang lebih canggih.

Itu seperti mengatakan "jika Anda membutuhkan aplikasi untuk meningkatkan sistem operasi Anda, OS Anda buruk". Tidak ada alat yang bisa melakukan segalanya. Filosofi unix adalah melakukan satu hal, dan melakukannya dengan baik . Itulah yang kami lakukan di sini. Compose melakukan satu hal "mengatur container untuk menjalankan aplikasi". Ini bukan alat otomasi build.

Itu seperti mengatakan "jika Anda membutuhkan aplikasi untuk meningkatkan sistem operasi Anda, OS Anda buruk". Tidak ada alat yang bisa melakukan segalanya. Filosofi unix adalah melakukan satu hal, dan melakukannya dengan baik. Itulah yang kami lakukan di sini.

Wow, saya pikir kita mencapai itikad buruk yang terbaik.

Sayangnya, komponen sederhana yang dapat digunakan kembali bukanlah bagaimana semuanya berjalan. Docker sekarang sedang membangun alat untuk meluncurkan server cloud, sistem untuk pengelompokan, dan berbagai fungsi: membangun gambar, menjalankan gambar, mengunggah, mengunduh, dan akhirnya bahkan melapisi jaringan, semuanya dikompilasi menjadi satu biner monolitik yang dijalankan terutama sebagai root di server Anda . Manifes penampung standar telah dihapus. Kita harus berhenti berbicara tentang kontainer Docker, dan mulai berbicara tentang Platform Docker. Ini tidak menjadi blok penyusun sederhana yang dapat disusun seperti yang kita bayangkan.

Jadi Anda dapat menjamin bahwa kami tidak akan pernah melihat "docker compose" menulis di Masuk ke dalam biner monolitik buruh pelabuhan untuk menjaga filosofi unix? https://www.orchardup.com/blog/orchard-is-joining-docker

Untuk melanjutkan tujuan awal itu, kami bergabung dengan Docker. Antara lain, kami akan terus berupaya menjadikan Docker pengalaman pengembangan terbaik yang pernah Anda lihat - baik dengan Fig, dan dengan memasukkan bagian terbaik Fig ke dalam Docker itu sendiri.

Jadi singkatnya tidak ada cara untuk melakukan hal-hal seperti memuat perlengkapan dengan menulis ..? Saya harus mengatakan saya terkejut ..
Cara resminya adalah menambahkan pemuatan perlengkapan ke wadah produksi saya? Atau untuk menulis skrip shell di sekitar file tulis saya? Dalam kasus selanjutnya saya juga bisa menjalankan 'docker run' seperti yang saya lakukan sebelumnya.

@discordianfish , Jika, entah bagaimana, seseorang akan menyadari fakta bahwa teknisi CI / CD harus mampu menangani peristiwa siklus hidup dan orkestrasi setidaknya pada tingkat yang sangat dasar, lalu siapa tahu buruh pelabuhan / buruh pelabuhan dapat jalan keluar dari pipeline pengembangan lokal dan infrastruktur pengujian dan mencari tempat di lebih banyak lingkungan produksi. Saya berharap siapa pun yang mengerjakan tumpukan akan mengatasi masalah ini, tetapi saya tidak akan menahan napas.

Lagipula, apa yang perlu dilakukan pada waktu build mungkin berbeda dari yang dibutuhkan saat runtime, dan yang dibutuhkan saat runtime sering kali bervariasi menurut lingkungan penerapan ...

Agak menjengkelkan untuk membuat skrip eksternal saya sadar apakah up akan membuat atau memulai container ...

Dan itu adalah hal-hal yang dapat dibantu oleh beberapa hook siklus hidup + perintah + variabel lingkungan.

Anda melihatnya dalam kerangka kerja manajemen layanan dan alat orkestrasi lainnya ... mengapa tidak di docker-compose?

Anda mungkin tertarik dengan https://github.com/dnephin/dobi , yang merupakan alat yang telah saya kerjakan yang dirancang untuk alur kerja tersebut.

@dnephin berhenti

Terima kasih atas komentar konstruktif Anda. Saya tidak menyadari bahwa saya telah menyebutkan dobi di utas ini 8 bulan yang lalu.

Jika Anda senang dengan Makefile / bash, itu bagus! Saya senang masalah Anda telah teratasi.

Menambahkan komentar terkait dengan topik ini di sini: https://github.com/docker/compose/issues/1341#issuecomment -295300246

@dnephin untuk yang ini, komentar saya bisa diterapkan:

Sedih sekali bahwa masalah ini telah ditutup karena beberapa penyimpangan terhadap evolusi: kecewa:

Nilai terbesar dari memiliki buruh pelabuhan adalah standarisasi

Itulah intinya. Jika kita bisa "hanya" menulis file .sh atau apa pun untuk melakukan pekerjaan tanpa menggunakan Docker Compose, mengapa Docker Compose ada? :bingung:

Kami dapat memahami bahwa itu adalah pekerjaan besar, seperti yang dikatakan @ shin-:

sayangnya terlalu banyak beban untuk didukung pada tahap proyek tersebut

:jantung:

Tapi Anda tidak bisa mengatakan "Buat skrip" yang artinya "Hei, itu terlalu sulit, kami tidak akan berhasil".

Jika sulit untuk melakukannya, cukup katakan "Ide Anda menarik, dan memenuhi beberapa kebutuhan, tetapi sangat sulit untuk dilakukan dan kami tidak memiliki sumber daya untuk melakukannya saat ini ... Mungkin Anda dapat mengembangkannya dan bertanya permintaan tarik "atau sesuatu seperti itu: bohlam:

Di # 1341, saya "hanya" melihat cara untuk menulis docker-compose.yml perintah seperti nmp install yang akan dijalankan sebelum atau sesudah beberapa kejadian (seperti pembuatan kontainer), seperti yang akan Anda lakukan dengan docker exec <container id> npm install misalnya.

Kasus penggunaan

Saya memiliki gambar NodeJS khusus dan saya ingin menjalankan npm install dalam wadah yang dibuat darinya, dengan docker-compose up --build .

Masalah saya adalah: kode aplikasi tidak ditambahkan ke dalam wadah, itu dipasang di dalamnya dengan volume, didefinisikan dalam docker-compose.yml :

custom-node:
    build: ../my_app-node/
    tty: true
    #command: bash -c "npm install && node"
    volumes:
     - /var/www/my_app:/usr/share/nginx/html/my_app

jadi saya tidak dapat menjalankan npm install di Dockerfile karena memerlukan kode aplikasi untuk memeriksa dependensi. Saya menjelaskan perilakunya di sini: http://stackoverflow.com/questions/43498098/what-is-the-order-of-events-in-docker-compose

Untuk menjalankan npm install , saya harus menggunakan solusi, pernyataan command :

command: bash -c "npm install && node"

yang tidak terlalu bersih: kecewa: dan yang tidak dapat saya jalankan pada versi Alpine (mereka tidak menginstal Bash di dalamnya).

Saya pikir Docker Compose akan menyediakan cara untuk menjalankan perintah exec pada container, misalnya:

custom-node:
    build: ../my_app-node/
    tty: true
    command: node
    volumes:
     - /var/www/my_app:/usr/share/nginx/html/my_app
    exec:
     - npm install

Tapi ternyata tidak, dan saya pikir itu benar-benar hilang!

Saya mengharapkan penulisan dirancang untuk pengujian, tetapi saya mungkin salah dan itu lebih ditujukan untuk pengembangan lokal dll. Saya menemukan beberapa sisi kasar lainnya seperti wadah yatim piatu dan hubungan yang tidak jelas antara nama proyek, jalur dan bagaimana itu digunakan untuk mengidentifikasi kepemilikan, apa yang terjadi jika Anda memiliki banyak file compose dalam direktori yang sama, dll. Jadi secara keseluruhan, sepertinya tidak cocok untuk CI.
Sebagai gantinya, saya berencana untuk menggunakan kembali manifes k8 produksi saya di CI dengan menjalankan kubelet standalone. Ini juga akan membutuhkan banyak lem, tapi setidaknya dengan cara ini saya bisa menggunakan deklarasi yang sama untuk dev, test dan prod.

@ lucile-sticky Anda dapat menggunakan sh -c di alpine.

Sepertinya yang Anda inginkan adalah "otomatisasi build" yang bukan merupakan peran docker-compose. Pernahkah Anda melihat dobi ?

Dua pertanyaan:

  • Mengapa ini bukan peran Docker Compose?
  • Jika intinya adalah hanya memiliki satu alat untuk mengatur semuanya, mengapa saya harus menggunakan alat lain untuk menyelesaikan tugas yang tidak dapat dilakukan oleh Docker Compose?

Fitur ini sangat dibutuhkan!

@ lile-lengket

Mengapa ini bukan peran Docker Compose?

Karena peran Compose didefinisikan dengan jelas dan tidak menyertakan fungsi tersebut.

Compose adalah alat untuk menentukan dan menjalankan aplikasi Docker multi-container. Dengan Tulis, Anda menggunakan file Tulis untuk mengonfigurasi layanan aplikasi Anda. Kemudian, dengan menggunakan satu perintah, Anda membuat dan memulai semua layanan dari konfigurasi Anda

Jika intinya adalah hanya memiliki satu alat untuk mengatur semuanya, mengapa saya harus menggunakan alat lain untuk menyelesaikan tugas yang tidak dapat dilakukan oleh Docker Compose?

Kami tidak ingin menjadi satu-satunya alat untuk mengatur semuanya. Kami mengikuti filosofi UNIX dan percaya pada "membuat setiap program melakukan satu hal dengan baik. Untuk melakukan pekerjaan baru, bangun dari awal daripada memperumit program lama dengan menambahkan fitur baru."
Tidak apa-apa untuk tidak setuju dengan filosofi itu, tetapi begitulah cara kami di Docker mengembangkan perangkat lunak.

Saya membuat masalah ini, pada Agustus 2015, setiap tahun seseorang menambahkan komentar dan kami mengulang pertanyaan yang sama dengan jawaban yang sama (dan pasti Anda akan melihat @dnephin membuat Iklan untuk alatnya).

@ shin-

Anda tidak dapat memisahkan "build" dan "provision" di alat orkestrasi.

Misalnya, mungkin Anda mengenal salah satunya:

Saat Anda mengkonfigurasi layanan, Anda harus menyediakannya. Jika saya menggunakan tomcat, saya harus menyediakannya dengan perang, jika saya membuat DB, saya harus menyuntikkan data, dll. Tidak peduli bagaimana wadah harus dimulai (biarkan pengelola gambar mengelolanya). Tujuan utama "penyedia" dalam kasus Compose adalah untuk menghindari kesalahpahaman antara "apa yang memulai penampung saya" dan "penyediaan apa itu".

Seperti kata kutipan Anda dalam dokumen tulis "Dengan Tulis, Anda menggunakan file Tulis untuk mengonfigurasi layanan aplikasi Anda. Kemudian , dengan menggunakan satu perintah, Anda membuat dan memulai semua layanan dari konfigurasi Anda"

Filsafat Unix? Biarkan aku tertawa. Saya mengarahkan Anda ke jawaban yang sama yang saya lakukan dalam masalah ini https://github.com/docker/compose/issues/1809#issuecomment -237195021.
Mari kita lihat bagaimana "moby" akan berkembang dalam filosofi Unix.

@ shin- docker-compose tidak mematuhi Filosofi Unix oleh imajinasi apa pun. Jika buruh pelabuhan-menulis mengikuti Unix Philosophy akan ada perintah diskrit untuk setiap build, up, rm, start, stop, dll dan masing-masing akan memiliki stdin, stdout, dan stderr yang dapat digunakan yang berperilaku konsisten. kata sysadmin unix dengan pengalaman lebih dari 20 tahun termasuk Sistem V, HP-UX, AIX, Solaris, dan Linux

Mari kembali ke ikhtisar untuk menulis

Compose adalah alat untuk menentukan dan menjalankan aplikasi Docker multi-container. Dengan Tulis, Anda menggunakan file Tulis untuk mengonfigurasi layanan aplikasi Anda. Kemudian, dengan menggunakan satu perintah, Anda membuat dan memulai semua layanan dari konfigurasi Anda.

Pada akhirnya, docker-compose adalah alat orkestrasi untuk mengelola sekelompok layanan berdasarkan container yang dibuat dari gambar buruh pelabuhan. Fungsi utamanya adalah untuk 'membuat', 'memulai', 'berhenti', 'skala', dan 'menghapus' layanan yang didefinisikan dalam file docker-compose.yml.

Banyak layanan memerlukan perintah tambahan untuk dijalankan selama setiap transisi siklus hidup ini. menskalakan cluster database sering kali memerlukan bergabung atau menghapus anggota dari cluster. penskalaan aplikasi web sering kali memerlukan pemberitahuan kepada penyeimbang beban bahwa Anda telah menambahkan atau menghapus anggota. beberapa sysadmin paranoid suka secara paksa membersihkan log database mereka dan membuat pos pemeriksaan saat mematikan database mereka.

Mengambil tindakan pada transisi status diperlukan untuk sebagian besar alat orkestrasi. Anda akan menemukannya di alat AWS, alat Google, mandor, koki, dll .. sebagian besar hal yang ada di ruang orkestrasi ini memiliki semacam pengait siklus hidup.

Saya pikir ini sangat sesuai dengan bidang penulisan buruh pelabuhan karena ini adalah alat orkestrasi dan menyadari perubahan status. Saya tidak merasa acara atau skrip eksternal sesuai dengan kasus penggunaan. Mereka tidak idempoten, jauh lebih sulit untuk meluncurkan layanan 'kedua' di samping menulis untuk mengikuti acara. Apakah pengait berjalan di dalam wadah atau di luar wadah merupakan detail implementasi.

Pada akhirnya, ada kebutuhan nyata yang diungkapkan oleh pengguna docker-compose dan @aanand , @dnephin , @ shin- sepertinya mengabaikannya. Akan menyenangkan melihat ini disertakan dalam peta jalan.

Jenis fungsi ini saat ini memblokir adopsi saya dari buruh pelabuhan dalam pengujian dan penerapan produksi produksi. Saya sangat ingin melihat ini ditangani dengan cara tertentu daripada diberhentikan.

Saya rasa ini akan sangat berguna!

Bagi saya masalahnya adalah ketika ada wadah aplikasi A menjalankan layanan 'a' bergantung pada db wadah B menjalankan layanan b. Kemudian kontainer A gagal kecuali b-nya diatur.
Saya lebih suka menggunakan image hub buruh pelabuhan daripada menulis ulang file Docker saya sendiri. Tetapi ini berarti A gagal dan tidak ada penampung yang dibuat. Satu-satunya pilihan adalah

  1. Gunakan B sebagai gambar dasar dan buat Dockerfile saya sendiri.
  2. Biarkan A gagal dan konfigurasikan b dalam skrip dan mulai ulang A.

Saya memiliki kasus penggunaan yang sama persis dengan @ lucile-sticky.

@lekhnath untuk kasus saya, saya menyelesaikannya dengan mengedit opsi command di docker-compose.yml :

command: bash -c "npm install && node"

Tapi TT itu sangat jelek

@ lucile-sticky Perlu dicatat bahwa ini mengesampingkan perintah apa pun yang disetel dalam Dockerfile kontainer. Saya mengatasi ini dengan memasang skrip shell khusus menggunakan volumes , membuat command di file Docker Compose saya menjalankan skrip itu, dan memasukkan di dalamnya CMD dari Dockerfile .

Mengapa masalah ini ditutup? _tulis skrip bash_ atau _ gunakan alat ini yang saya tulis_ bukan alasan yang valid untuk menutup masalah ini.

Ini adalah fitur yang sangat berguna dan penting yang diperlukan dalam banyak kasus penggunaan di mana penulisan digunakan.

@dnephin Menurut Anda, menjalankan skrip init berada di luar cakupan penerapan aplikasi berbasis kontainer? lagipula, compose adalah tentang "mendefinisikan dan menjalankan aplikasi multi-container dengan Docker".

Apakah seseorang melihat dobi jika Anda belum melakukannya di sini :)
image

Menebak tidak ada yang terjadi dengan ini. Saya ingin melihat beberapa jenis fungsi dalam file docker-compose mana kita dapat menulis kapan perintah harus dijalankan seperti contoh yang diberikan @ ahmet2mir .

Sangat menyedihkan melihat fitur ini tidak diterapkan.

Harap implementasikan fitur ini, saya perlu menginstal file secara otomatis setelah docker-compose, karena folder tempat file harus disalin dibuat setelah inisialisasi container.
Terima kasih

Sungguh luar biasa bahwa fitur ini belum diimplementasikan!

Ini adalah bentuk yang sangat buruk @dnephin. Anda telah menghambat penerapan fitur yang sangat dicari untuk apa yang tampaknya sebagian besar adalah promosi diri, dan Anda bahkan tidak bersedia melanjutkan percakapan.

Maaf, saya tidak bisa memikirkan bahasa yang lebih ringan untuk menjelaskannya, kurangnya fitur ini telah menambahkan sebagian kecil ke alur kerja kita, seperti banyak pengembang dan tim lainnya, dan Anda telah menjadi penghalang untuk memecahkan masalah ini ..

Oh, mari kita jadikan unix-way begitu.
_Hanya_ (lalu multipleks) pipa docker-compose up stdin ke setiap kontainer ' CMD ?
Sehingga file yaml seperti itu

services:
  node:
    command: sh -

akan membuat ini berhasil: cat provision.sh | docker-compose up
kontainer untuk hal-hal uting exec, saya tidak melihat lebih baik menggunakan stdin daripada lewat perintah bersama.

Alternatifnya bisa jadi:

services:
  node:
    localscript: provision.sh

Meskipun sedikit shell-centric yang akan menyelesaikan 99% kasus penggunaan penyediaan.

Meskipun ada kasus penggunaan yang valid, dan banyak suara positif tentang ini ... tampaknya masih ditolak. Malu karena saya, seperti banyak orang lain di sini, akan menganggap ini sangat berguna.

Menambahkan +1 saya ke tumpukan besar + yang ada

... +1 lainnya di sini!

Menurut saya, jika ada permintaan untuk fitur ini, fitur ini harus diterapkan, alat ada di sini untuk membantu kita mencapai tujuan dan kita harus membentuknya untuk membantu kita tidak mempersulit hidup kita.
Saya memahami filosofi yang dipatuhi seseorang tetapi menambahkan semacam "perintah kait" seharusnya tidak menjadi masalah.

+1 +1

Sementara saya menunggu fitur ini, saya menggunakan skrip berikut untuk melakukan tugas serupa:

docker-start.sh

#!/usr/bin/env bash

set -e
set -x

docker-compose up -d
sleep 5

# #Fix1: Fix "iptable service restart" error

echo 'Fix "iptable service restart" error'
echo 'https://github.com/moby/moby/issues/16137#issuecomment-160505686'

for container_id in $(docker ps --filter='ancestor=reduardo7/my-image' -q)
  do
    docker exec $container_id sh -c 'iptables-save > /etc/sysconfig/iptables'
  done

# End #Fix1

echo Done

@ reduardo7 Maka Anda sebaiknya juga menghapus docker-compose sama sekali, dengan cara itu mengurangi ketergantungan satu.

@omeid , kamu benar! Ini adalah solusi untuk melakukan tugas serupa, maaf!

@ reduardo7 Tidak perlu meminta maaf, apa yang telah Anda posting mungkin akan berguna bagi sebagian orang.
Saya hanya menunjukkan bahwa masalah asli masih berlaku dan seharusnya tidak ditutup. :)

Saya memahami kepanjangan dari @dnephin , fungsi yang disebutkan di sini dapat diganti dengan fitur yang cukup berbeda.

Namun, jika pola seperti itu sering digunakan, bagaimana dengan menyajikan panduan (atau beberapa tes) sehingga orang lain dapat dengan mudah menggunakannya?

Tampaknya tidak ada perbedaan pendapat bahwa pola ini dapat sering digunakan.

@MaybeS Satu-satunya ketidaksepakatan adalah bahwa @dnephin lebih suka melihat alat

@omeid ya memang.

contoh hari ini menginginkan cara untuk menulis untuk melakukan beberapa bentuk onrun

version: "3.3"
services:
  gitlab:
    image: 'gitlab/gitlab-ce:latest'
    restart: always
    hostname: 'gitlab'
    environment:
      GITLAB_OMNIBUS_CONFIG: |
        # NOTE: this URL needs to be right both for users, and for the runner to be able to resolve :() - as its the repo URL that is used for the ci-job, and the pull url for users.
        external_url 'http://gitlab:9090'
        gitlab_rails['gitlab_shell_ssh_port'] = 2224
    ports:
      - '9090:9090'
      - '2224:22'
  gitlab-runner:
    image: gitlab/gitlab-runner:latest
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock

dan tentu saja, pelari tidak terdaftar - dan untuk melakukan itu, kami harus melakukannya

  1. tarik token keluar dari database di gitlab
  2. jalankan register di runner container

jadi alih-alih menentukan penerapan aplikasi multi-container saya hanya dengan docker-compose, saya perlu menggunakan beberapa cara sekunder - dalam hal ini ... docs?

export GL_TOKEN=$(docker-compose exec -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c "SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1"')
docker-compose exec gitlab-runner gitlab-runner register -n \
  --url http://gitlab:9090/ \
  --registration-token ${GL_TOKEN} \
  --executor docker \
  --description "Docker Runner" \
  --docker-image "docker:latest" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock \
  --docker-network-mode  "network-based-on-dirname-ew_default"

mmm, saya mungkin bisa meretas sesuatu, di mana saya memiliki wadah lain yang memiliki soket buruh pelabuhan, dan docker exec's

apa yang harus dipertaruhkan pasti ada jalan ....

misalnya, saya dapat menambahkan:

  gitlab-initializer:
    image: docker/compose:1.18.0
    restart: "no"
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./gitlab-compose.yml:/docker-compose.yml
    entrypoint: bash
    command: -c "sleep 200 && export GL_TOKEN=$(docker-compose -p sima-austral-deployment exec -T -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c \"SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1\"') && docker-compose exec gitlab-runner gitlab-runner register -n --url http://gitlab:9090/ --registration-token ${GL_TOKEN} --executor docker --description \"Docker Runner\" --docker-image \"docker:latest\" --docker-volumes /var/run/docker.sock:/var/run/docker.sock --docker-network-mode  \"simaaustraldeployment_default\""

ke file buat saya - meskipun saya memerlukan semacam loop / tunggu, karena gitlab belum siap langsung - sleep 200 mungkin tidak cukup.

jadi - Anda __dapat__ meretas beberapa jenis pola seperti ini secara langsung di docker-compose.yml - tetapi secara pribadi, saya lebih suka dukungan yang lebih bersih daripada ini :)

@SvenDowideit onrun sudah ada, entrypoint atau cmd .

Script entrypoint untuk gambar ini bahkan menyediakan pengait untuk Anda. $GITLAB_POST_RECONFIGURE_SCRIPT dapat disetel ke jalur skrip yang akan dijalankan setelah semua penyiapan selesai (lihat /assets/wrapper pada gambar). Setel variabel env ke jalur skrip Anda yang melakukan register psql + dan Anda sudah siap.

Sekalipun gambar tidak menyediakan pengait ini, itu adalah sesuatu yang dapat ditambahkan dengan cukup mudah dengan memperluas gambar.

meskipun saya perlu beberapa jenis loop / tunggu, karena gitlab belum siap langsung - sleep 200 mungkin tidak cukup.

Ini akan diperlukan bahkan dengan opsi "exec-after-start". Karena skrip entrypoint sebenarnya menyediakan pengait, saya pikir itu mungkin tidak perlu dengan solusi itu.

tidak, saya (pikir) Anda melewatkan bagian dari masalah yang saya tunjukkan:

dalam kasus saya, saya memerlukan akses ke kedua container, bukan hanya satu - jadi entrypoint / command _not_ memberi saya ini.

GL_TOKEN berasal dari wadah gitlab, dan kemudian digunakan dalam wadah gitlab-runner untuk mendaftar.

jadi peretasan yang saya lakukan, adalah menggunakan gambar docker/compose untuk menambahkan penampung ketiga - ini bukan sesuatu yang dapat Anda ubah dari konfigurasi / titik entri / pengaturan penampung, dan sepenuhnya merupakan contoh (sepele) dari a koordinasi multi-wadah yang membutuhkan lebih banyak.

Saya telah mengerjakan beberapa hal untuk membuatnya sedikit lebih ajaib - yang pada dasarnya berarti wadah inisialisasi saya memiliki beberapa loop tidur, karena gitlab membutuhkan waktu untuk memulai sendiri.

TBH, saya mulai merasa bahwa dengan menggunakan skrip, berjalan di init-container yang menggunakan file compose itu sendiri dan gambar docker / compose, _is_ cara yang tepat untuk menyembunyikan kerumitan semacam ini - untuk non-produksi "coba saya keluar, dan itu hanya akan bekerja "situasi seperti ini.

_IF_ Saya harus mempertimbangkan beberapa gula sintaksis yang aneh untuk membantu, mungkin saya akan memilih sesuatu seperti:

gitlab-initializer:
    image: docker/compose:1.18.0
    restart: "no"
    volumes:
    - /var/run/docker.sock:/var/run/docker.sock
    - ./gitlab-compose.yml:/docker-compose.yml
    entrypoint: ['/bin/sh']
    command: ['/init-gitlab.sh']
    file:
      path: /init-gitlab.sh
      content: |
            for i in $(seq 1 10); do
                export GL_TOKEN=$(docker-compose -f gitlab-compose.yml -p sima-austral-deployment exec -T -u gitlab-psql gitlab sh -c 'psql -h /var/opt/gitlab/postgresql/ -d gitlabhq_production -t -A -c "SELECT runners_registration_token FROM application_settings ORDER BY id DESC LIMIT 1"')
                echo "$i: token($?) == $GL_TOKEN"
                ERR=$?

                if [[ "${#GL_TOKEN}" == "20" ]]; then
                    break
                fi
                sleep 10
            done
            echo "GOT IT: token($ERR) == $GL_TOKEN"

            for i in $(seq 1 10); do
                if  docker-compose -f gitlab-compose.yml  -p sima-austral-deployment exec -T gitlab-runner \
                    gitlab-runner register -n \
                    --url http://gitlab:9090/ \
                    --registration-token ${GL_TOKEN} \
                    --executor docker \
                    --description "Docker Runner" \
                    --docker-image "docker:latest" \
                    --docker-volumes '/var/run/docker.sock:/var/run/docker.sock' \
                    --docker-network-mode  "simaaustraldeployment_default" ; then
                        echo "YAY"
                        break
                fi
                sleep 10
            done

misalnya, seperti cloud-init: http://cloudinit.readthedocs.io/en/latest/topics/examples.html#writing -out-arbitrary-files

tetapi ketika tiba saatnya - kami _memiliki_ solusi untuk mengoordinasikan hal-hal multi-container yang rumit dari dalam docker-compose-yml.

Jika Anda dapat menyetel token yang telah ditentukan sebelumnya, Anda dapat melakukannya dari skrip entrypoint di gitlab-runner . Apakah tidak ada cara untuk mengatur waktu itu?

@dnephin Saat Anda menyebutkan skrip, Anda meleset dari satu tahun cahaya dan kemudian beberapa.

onrun tidak sama dengan entrypoint atau cmd .

entrypoint / cmd adalah untuk mengkonfigurasi executable yang akan dijalankan sebagai kontainer init / PID 1.

Ide yang disebutkan dalam hal ini dan banyak masalah terkait adalah tentang init scripts , yang berbeda dari init dalam konteks booting, dan tentang skrip init aplikasi, pikirkan pengaturan database.

@dnephin mungkin akan lebih berguna jika Anda berfokus pada kumpulan masalah umum, daripada mencoba mengatasi masalah kumpulan penampung tertentu.

Dari apa yang saya lihat, tidak, ini adalah rahasia yang dihasilkan - tetapi pada kenyataannya, ini bukan satu-satunya persyaratan koordinasi multi-kontainer bahkan dalam sistem permainan kecil ini yang mungkin dimiliki - itu hanya yang tercepat bagi saya untuk prototipe di depan umum.

Bagaimana mungkin kami dapat mengganti entrypoint dan command dalam file penulisan sejak v1 (https://docs.docker.com/compose/compose-file/compose-file -v1 / # entrypoint) dan masih tidak memiliki arahan seperti onrun untuk menjalankan perintah saat kontainer sudah aktif?

TBH, menurut saya onrun tidak masuk akal - Docker, atau orchestrator tidak tahu apa arti "container all up" - dalam salah satu kasus saya, HEALTHCHECK akan gagal, sampai setelah saya melakukannya beberapa "barang" tambahan di mana saya mendapatkan info dari satu wadah, dan menggunakannya untuk menendang beberapa hal lain di wadah lain.

Dan _if_ Saya grok benar, ini berarti saya pada dasarnya membutuhkan wadah Operator, yang berisi kode yang mendeteksi ketika beberapa bagian dari sistem multi-kontainer cukup siap untuk melakukan beberapa pekerjaan, (bilas dan ulangi), hingga itu baik menyelesaikan tugasnya dan keluar, atau bahkan mungkin memonitor dan memperbaikinya.

Dan bagi saya ini terasa seperti pekerjaan yang paling baik diselesaikan (dalam pembuatan-buruh pelabuhan) oleh wadah penulisan-buruh pelabuhan dengan kode.

Saya mungkin akan bermain-main dengan bagaimana kemudian mengubah operator ini menjadi sesuatu yang dapat menangani tumpukan kawanan buruh pelabuhan (karena kebutuhan proyek lain).

Saya tidak sepenuhnya yakin ada banyak gula sintaksis yang dapat ditambahkan ke docker-compose, kecuali itu sesuatu seperti menandai wadah sebagai "ini adalah operator, berikan kemampuan sihir".

Jelas terlihat bahwa pengembang tidak ingin mendengarkan pengguna .. Saya akan melihat beberapa alat lain ... docker-compose sangat merepotkan .. Saya tidak mengerti mengapa Anda tidak dapat memahami bahwa satu-satunya hal berguna yang datang dari buruh pelabuhan-komposer adalah alat pembangunan ... Saya menghabiskan banyak waktu untuk mencari BAGAIMANA saya dapat menjalankan perintah SEDERHANA untuk menambahkan izin di dalam wadah ke pengguna aktif ..

Tampaknya docker-composer memiliki status BELUM SELESAI ...

Saya juga menginginkan sesuatu yang onrun dalam file penulisan saya

__BUT__, baik container, maupun compose tidak memiliki cara untuk mengetahui apa artinya onrun . Inilah mengapa pola operator ada, dan mengapa saya membuat contoh di https://github.com/docker/compose/issues/1809#issuecomment -362126930

__is__ mungkin untuk melakukan ini hari ini - intinya, Anda menambahkan layanan onrun yang menunggu sampai layanan lain apa pun benar-benar siap untuk berinteraksi (dalam kasus gitlab, itu membutuhkan cukup banyak waktu), lalu lakukan apa pun yang perlu Anda lakukan untuk mengoordinasikan berbagai hal.

Jika ada _adalah_ sesuatu yang tidak bekerja dengan itu, tolong beritahu kami, dan kami akan melihat apakah kami dapat menemukan sesuatu!

Saya juga menginginkan sesuatu yang akan terus berjalan di file tulis saya

TAPI, baik container, maupun compose tidak memiliki cara untuk mengetahui apa arti onrun.

Seperti yang saya lihat, onrun per layanan, berarti saat proses penampung pertama dimulai. Dalam sejumlah besar kasus, penampung hanya menjalankan satu proses, karena ini adalah cara yang disarankan untuk menjalankan penampung.

Masalah dukungan lintas platform telah diselesaikan sebelumnya, karena perintah tersebut dapat sepenuhnya OS agnostik melalui docker exec , dengan cara yang sama RUN tidak harus berarti perintah linux di Dockerfile.
https://docs.microsoft.com/en-us/virtualization/windowscontainers/manage-docker/manage-windows-dockerfile

Masih menunggu fitur onrun

Saya memerlukan fitur onrun ini juga, saya pikir itu ada di alat ini. Karena fitur yang kurang ini sekarang saya perlu memelihara 2 skrip man.

Guys, bagaimana jika saya membuat pembungkus di sekitar docker-compose dan mengizinkan fitur onrun ini? Apakah kalian akan menggunakannya?

@wongjiahau mungkin seperti ini? https://github.com/docker/compose/issues/1809#issuecomment -348497289

@ reduardo7 Ya, saya berpikir untuk membungkusnya di dalam skrip bernama docker-composei , dan dengan docker-composei.yml yang berisi atribut onrun .
Btw, docker-composei berarti docker-compose improved .

Solusi sebenarnya mungkin dengan membangun image 'Orchestrator' yang menjalankan dan mengelola (melalui skrip bash) 'App Images' (mungkin menggunakan buruh pelabuhan) secara internal. Jika tidak, kami akan selalu meminta lebih banyak fitur untuk alat yang "tidak dimaksudkan untuk melakukan apa yang kami inginkan".

Jadi kita bahkan harus mempertimbangkan Docker di dalam Docker ...

hanya untuk menambahkan dukungan saya untuk fitur yang diusulkan ini. onrun memang masuk akal, tetapi untuk sedikit memperluas kegunaan potensial dan bukti masa depan, mungkin seseorang perlu melihat arsitektur 'onevent' yang lebih luas, salah satunya adalah onrun.

Mengingat arah yang berlaku untuk kontainer menjadi mandiri, satu layanan per kontainer, kontainer harus mandiri dalam hal kesadaran konteks operasinya. Apa yang mengalir dari file compose itu harus menjadi media untuk mendefinisikannya, bukan skrip baut. Sulit untuk membantahnya, kecuali jika Anda adalah seorang fanatik yang egois.

Dalam kasus saya, wadah redis saya memuat skrip lua setelah server redis dimulai. Dalam lingkungan non-kontainer normal saya mendapatkan systemd untuk menjalankan skrip pasca-startup. Sederhana dan konsisten dengan arsitektur systemd. Prinsip serupa harus ada untuk compose mengingat perannya dalam menyiapkan konteks untuk menjalankan container.

Sebagai saran umum untuk pengelola, harap fokus pada prinsip operasi yang telah terbukti, bukan preferensi pribadi.

jadi solusinya (setelah membaca semua utas ini) adalah menggunakan skrip bash untuk melakukan pekerjaan ... dalam hal ini saya akan menghapus docker-compose (kita dapat melakukan semuanya dengan docker cmd ...)

terima kasih untuk mendengarkan orang-orang yang menggunakan barang-barang Anda :)

Dengan melihat jumlah pesan yang berisi argumen dan argumen tandingan yang melawan proposisi sederhana (seperti mengadakan acara

Tolong, mari kita buat Open Source benar-benar _open_.

ada pembaruan tentang fitur ini? Apa masalahnya?

@ v0lume Saya

Sepertinya masih belum ada solusi ... Namun, saya ingin membagikan solusi hacky.
Dengan menetapkan versi "2.1" di docker-compose.yml, Anda dapat menyalahgunakan uji healthcheck untuk menjalankan kode tambahan di dalam gambar saat dimulai. Berikut ini contohnya:

version: '2.1'
services:
    elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch:5.4.3
        healthcheck:
            test: |
                curl -X PUT elasticsearch:9200/scheduled_actions -H "ContentType: application/json" -d '{"settings":{"index":{"number_of_shards":'1',"number_of_replicas":'0'}}}' &&
                curl --silent --fail localhost:9200/_cat/health ||
                exit 1
            interval: 11s 
            timeout: 10s 
            retries: 3
        environment:
            - discovery.type=single-node
            - ES_JAVA_OPTS=-Xms1g -Xmx1g
            - xpack.security.enabled=false
    main:
        image: alpine
        depends_on:
            elasticsearch:
                condition: service_healthy

Jika skrip healthcheck-test yang Anda tulis keluar dengan kode> = 1, mungkin akan dijalankan beberapa kali.
Healthcheck suatu layanan hanya akan dijalankan jika layanan lain bergantung padanya dan menetapkan kondisi service_healthy seperti yang terlihat pada contoh.

Saya suka pendekatan @ T-vK dan pernah menggunakannya dengan sukses sebelumnya. Tapi saya ingin berbagi ... peretasan lainnya:

# Run Docker container here

until echo | nc --send-only 127.0.0.1 <PORT_EXPOSED_BY_DOCKER>; do
  echo "Waiting for <YOUR_DOCKER> to start..."
  sleep 1
done

# Do your docker exec stuff here

+1
Saya sangat setuju dengan ini karena fitur ini diperlukan dan sudah diimplementasikan oleh orkestra buruh pelabuhan lain seperti kubernetes. Ini sudah memiliki kait siklus hidup untuk kontainer dan didokumentasikan di sini .

Tetapi izinkan saya memberikan kasus penggunaan yang tidak dapat Anda selesaikan dengan Dockerfiles.

Katakanlah Anda perlu memasang volume saat runtime dan membuat tautan simbolis dari penampung Anda ke volume tanpa mengetahui nama persis direktori tersebut. Saya memiliki kasus bahwa nama dir dinamis tergantung pada lingkungan tempat saya menerapkan dan saya meneruskannya sebagai variabel.

Tentu saya menemukan solusi untuk menyelesaikan ini dan ada lebih dari satu. Di sisi lain, pengait akan memberi saya fleksibilitas dan pendekatan yang lebih baik untuk secara dinamis membuat perubahan tanpa dorongan untuk meretas dan mengganti Dockerfile.

Saya senang menemukan masalah ini. Saya telah bermain-main dengan Docker dan Docker compose selama beberapa tahun. Sekarang serius berharap untuk menggunakannya sebagai alat untuk mulai menskalakan sistem. Saya akan memeriksa kembali setiap satu atau dua tahun, tetapi berdasarkan sikap pengelola proyek, saya hanya akan menggunakan salah satu skrip, atau alat lainnya. Senang tidak menginvestasikan banyak waktu dan menemukan yang ini sejak dini.

Kiat Pro: Jika seseorang yang baru mulai memindahkan alur kerja mereka ke alat jenis ini sudah membutuhkan apa yang dijelaskan di sini, mungkin ada baiknya memikirkan kembali 'mengapa' Anda membuat ini. Ya, Anda sukses, tetapi itu karena orang-orang menggunakan barang itu pada awalnya, dan Anda mungkin sangat terbuka untuk memberi mereka apa yang mereka butuhkan.

Semua yang terbaik.

Saya dapat memberikan apa pun yang Anda inginkan (kecuali pacar saya) jika fitur ini diterapkan dan saya akan menjadi orang paling bahagia di seluruh alam semesta :)

hanya untuk menambahkan dukungan saya untuk fitur yang diusulkan ini. onrun memang masuk akal, tetapi untuk sedikit memperluas kegunaan potensial dan bukti masa depan, mungkin seseorang perlu melihat arsitektur 'onevent' yang lebih luas, salah satunya adalah onrun.

Itu akan menyenangkan.

Untuk menambah ini, diberikan yang berikut:

services:
    web:
        image: node:8-alpine
        depends_on:
            - db
    db:
        image: postgres:alpine
        onrun: "echo hi"

apakah terlalu berlebihan untuk menambahkan skrip lintas acara?

    web:
        events:
            db_onrun: "connectAndMigrate.sh"

Menurut pendapat saya, menambahkan ini ke docker-compose sangat mudah bahwa tidak hanya Anda, yang menggunakan file compose dan compose stack, tetapi juga developer lain di tim Anda.

  • Menggunakan wadah terpisah - setiap orang harus tahu bahwa mereka harus menjalankannya.
  • Tulis Dockerfile khusus - kami memiliki sekitar 20 layanan dan untuk setiap layanan saya harus mengganti Dockerfile untuk menjalankan beberapa perintah.

Kita perlu menginstal dan mengkonfigurasi mkcert , misalnya, pada setiap lingkungan untuk memiliki sertifikat terpercaya. Ini bukan bagian dari kontainer atau Dockerfile karena tidak diperlukan pada tahap / produksi. Apa pendekatan yang tepat di sini untuk menginstal alat dan semua orang yang menggunakan file compose bahkan tidak tahu apa yang terjadi di balik layar?

Menambahkan kasus penggunaan lain:

Membutuhkan contoh wordpress. Menulis buruh pelabuhan-compose.yaml saya. docker-compose up - Ups! Perlu menyetel izin file dari direktori plugin ... Tidak dapat menemukan cara lain untuk membuatnya bekerja, harus menyetel izin setelah penampung berjalan karena saya mengikat beberapa file dari host dan tampaknya satu-satunya cara untuk memperbaiki izin fs adalah dengan melakukan chown -Rf www-data.www-data /var/www/wp-content dari dalam wadah. Tulis Dockerfile saya sendiri dan buat, hanya untuk ini? Itu tampak bodoh bagiku.

Untungnya bagi saya, peretasan healthcheck diberikan di atas memungkinkan saya untuk menerapkan ini. Saya melihat halaman lain di web berbicara tentang masalah izin pengaturan pada volume buruh pelabuhan, tetapi solusi yang disarankan tidak berfungsi.

Senang melihat penjaga gerbang ini, @dnephin , @aanand , @ shin-, mendapatkan banyak panas untuk ini. Itu benar-benar berbicara banyak ketika seluruh komunitas berteriak sekeras mungkin, dan pengembang inti hanya duduk, bertahan, dan menolak untuk mendengarkan. Begitu khas juga. Mari kita hitung tidak hanya jumlah yang diacungi jempol, tetapi juga 34 pengguna yang menjawab bahwa ini diperlukan:
01) sshishov
02) fescobar
03) sandor11
04) web-ted
05) v0lume
06) webpolis
07) Skull0ne
08) usergoodvery
09) wongjiahau
10) MFQ
11) yosefrow
12) roti bagermen
13) daqSam
14) omeid
15) dantebarba
16) willyyang
17) SharpEdgeMarshall
18) kehilangan pembawa
19) hantu
20) rodrigorodriguescosta
21) datatypevoid
22) dextermb
23) lekhnath
24) lucile-sticky
25) rav84
26) tolol
27) ahmet2mir
28) montera82
29) ikan discordian
30) jasonrhaas
31) fferraris
32) hypergig
33) sisi matahari
34) sthulb

Dan nomor yang bilang tidak? 3 kekalahan:
01) dnephin
02) aanand
03) tulang kering

Hmmm ... 34 sampai 3 ...

@ rm-rf-etc analitik yang bagus ... Saya bahkan tidak berpikir @dnephin atau @aanand sedang mengerjakan docker-compose lagi. Dengan keberuntungan, Docker berencana untuk menghentikan penulisan untuk tumpukan dan tidak akan ada tim yang tersisa untuk mengeluh tentang dan kami akan mulai melihat kemajuan produk lagi.

Menambahkan kasus penggunaan lain:

Membutuhkan contoh wordpress. Menulis buruh pelabuhan-compose.yaml saya. docker-compose up - Ups! Perlu menyetel izin file dari direktori plugin ... Tidak dapat menemukan cara lain untuk membuatnya bekerja, harus menyetel izin setelah penampung berjalan karena saya mengikat beberapa file dari host dan tampaknya satu-satunya cara untuk memperbaiki izin fs adalah dengan melakukan chown -Rf www-data.www-data /var/www/wp-content dari dalam wadah.

Dalam kasus ini, Anda juga dapat menyetel properti user di file Tulis Anda

Tulis Dockerfile saya sendiri dan buat, hanya untuk ini? Itu tampak bodoh bagiku.

Sepertinya Anda telah membentuk opini yang kuat; tetapi secara realistis, tidak ada yang "bodoh" tentang menulis Dockerfile untuk memodifikasi gambar dasar agar sesuai dengan kebutuhan Anda. Itulah maksud asli dari semua gambar dasar.

Untungnya bagi saya, peretasan healthcheck diberikan di atas memungkinkan saya untuk menerapkan ini. Saya melihat halaman lain di web berbicara tentang masalah izin pengaturan pada volume buruh pelabuhan, tetapi solusi yang disarankan tidak berfungsi.

Senang melihat penjaga gerbang ini, @dnephin , @aanand , @ shin-, mendapatkan banyak panas untuk ini.

Ya, sikap yang baik sobat. : D


@ rm-rf-etc analitik yang bagus ... Saya bahkan tidak berpikir @dnephin atau @aanand sedang mengerjakan docker-compose lagi.

Ya, sudah beberapa tahun sekarang - tidak perlu terus-menerus mem-ping mereka tentang masalah lama.

Dengan keberuntungan, Docker berencana untuk menghentikan penulisan untuk tumpukan dan tidak akan ada tim yang tersisa untuk mengeluh tentang dan kami akan mulai melihat kemajuan produk lagi.

🙄

@ shin- tetapi Anda baru saja mem-pingnya dengan respons itu

Saya baru-baru ini mengalami masalah ini lagi dan meskipun itu dapat dilakukan seperti yang terlihat dalam solusi saya, ini hanya berfungsi jika Anda menentukan 2.1, yang menyebalkan.

Ini hanya membingungkan saya bahwa sikap resminya adalah Anda harus membuat gambar buruh pelabuhan Anda sendiri untuk semuanya.
Bagi saya ini secara harfiah seperti mengatakan "Jika Anda ingin mengubah pengaturan dalam program apa pun, Anda harus mengubah kode sumber dan mengkompilasinya kembali.".
Setiap kali Anda menambahkan layanan baru atau Anda ingin meningkatkan ke versi yang lebih baru .. misalnya gambar MongoDB atau MySQL Docker, Anda harus membuat Dockerfile baru, membangunnya dan berpotensi mendorongnya ke registri Anda.
Ini adalah pemborosan waktu dan sumber daya yang sangat besar dibandingkan dengan bagaimana jadinya jika Anda bisa mengubah image: mongo:3.0.2 menjadi image: mongo:3.0.3 di docker-compose.yml Anda.
Saya tidak mengomel tentang waktu build yang lama, saya mengomel tentang fakta bahwa Anda harus repot dengan Dockerfiles dan docker build ketika yang Anda inginkan hanyalah memperbarui atau mengubah parameter layanan yang berpotensi bahkan tidak dimaksudkan untuk digunakan sebagai gambar dasar.

Dan argumen bahwa setiap aplikasi harus melakukan satu hal dan hanya satu hal, sangat menyebalkan. Ini bahkan bukan tentang mengimplementasikan fitur yang benar-benar baru, ini hanya tentang meneruskan parameter lain ke docker . Ini juga menimbulkan pertanyaan mengapa docker run , docker build , docker exec , docker pull dll. Semuanya adalah bagian dari aplikasi yang sama. Argumen tersebut terdengar agak munafik sekarang, bukan?

@ shin-, Saya mengikuti tautan Anda dan saya tidak melihat bagaimana properti pengguna relevan dengan pengaturan pemilik direktori bind mount. Sepertinya terkait dengan port.

Re: sikap: Sepertinya orang setuju dengan saya, jadi anggap itu sebagai umpan balik yang kuat. Maaf jika Anda tidak suka bagaimana saya mengungkapkan ini, tetapi sepertinya permintaan pengguna diabaikan, jadi apa lagi yang Anda harapkan?

Saya datang ke sini berharap untuk fungsionalitas seperti onrun: disarankan karena saya hanya dua hari menggunakan compose dan bagi saya alat seperti ini harus memiliki fungsi ini.

Kembali ke file buruh pelabuhan saya untuk memperbarui masing-masing dengan skrip terpisah untuk fitur tampaknya berlebihan. Saya hanya ingin menyuntikkan token dari wadah lain ke dalam variabel lingkungan di mana dockerfile saya fleksibel sebelumnya sekarang digabungkan dengan erat ke docker-composer.yml dan solusi untuk tujuan yang sederhana.

Sial, saya membaca seluruh utas melompat untuk menemukan jawaban "ok guys, kami akhirnya menyadari bahwa ini keren dan kami akan menerapkannya". Sedih melihat ini tidak bergerak maju.
1 untuk onrun!

@fabiomolinar , Ada satu jenis solusi, yang kami gunakan secara ekstensif dalam kawanan produksi kami, tetapi itu tidak sebaik mengadakan acara.

Kami menggunakan jangkar berikut

#### configure a service to run only a single instance until success
x-task: &task
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: on-failure
    replicas: 1
  # for compose (not supported by stack)
  restart: on-failure

mengulangi tugas sampai berhasil. Kami membuat penampung untuk migrasi dan tugas penyiapan yang memiliki hasil idempoten dan menjalankannya seperti ini di penulisan lokal dan di tumpukan kami.

Layanan yang bergantung pada tugas harus gagal dengan baik jika pekerjaan konfigurasi belum selesai. Dalam kebanyakan kasus selama Anda baik-baik saja dengan beberapa kesalahan yang menimpa pengguna akhir, ini memberi Anda konsistensi akhirnya yang akan bekerja dengan baik di sebagian besar lingkungan.

Ini juga mengasumsikan wadah layanan Anda dapat bekerja dengan status penyelesaian tugas sebelum dan sesudah. Dalam kasus penggunaan seperti migrasi database, layanan yang bergantung harus dapat bekerja dengan skema pra-dan pasca-migrasi .. jelas beberapa pemikiran harus dimasukkan ke dalam pengembangan dan koordinasi penyebaran, tetapi itu adalah fakta umum kehidupan bagi siapa saja yang melakukan pembaruan berkelanjutan dari layanan.

@fabiomolinar , berikut adalah contoh bagaimana kami menggunakan pendekatan ini dalam layanan tulis kami ...

#### configure a service to run only a single instance until success
x-task: &task
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: on-failure
    replicas: 1
  # for compose (not supported by stack)
  restart: on-failure

#### configure a service to always restart
x-service: &service
  # for docker stack (not supported by compose)
  deploy:
    restart_policy:
      condition: any
  # for compose (not supported by stack)
  restart: always

services: 
  accounts: &accounts
    <<: *service
    image: internal/django
    ports:
      - "9000"
    networks:
      - service
    environment:
      DATABASE_URL: "postgres://postgres-master:5432/accounts"
      REDIS_URL: "hiredis://redis:6379/"

  accounts-migrate:
    <<: *accounts
    <<: *task
    command: ./manage.py migrate --noinput

Terima kasih telah menunjukkannya pada @dopry. Tapi kasus saya agak lebih sederhana. Saya perlu menjalankan server saya dan kemudian, hanya setelah itu aktif dan berjalan, saya perlu melakukan beberapa tugas penerapan. Hari ini saya menemukan cara untuk melakukannya dengan melakukan beberapa manajemen proses kecil dalam satu baris CMD . Bayangkan bahwa server dan proses penerapan masing-masing disebut server dan deploy . Saya kemudian menggunakan:

CMD set -m; server $ deploy && fg server

Baris di atas menyetel mode monitor bash, lalu memulai proses server di latar belakang, lalu menjalankan proses deploy dan akhirnya membawa proses server ke latar depan lagi untuk menghindari Docker membunuh kontainer.

Sementara kita membahas ini, ada yang punya tip tentang cara menjalankan perintah pada container atau host saat menjalankan docker-compose up ?

Saya memahami bahwa menjalankan perintah apa pun pada host akan membahayakan lapisan keamanan, tetapi saya hanya ingin rm direktori sebelum atau selama startup wadah. Direktori dapat diakses di host dan container. Saya tidak ingin membuat image Docker kustom atau memiliki skrip yang pertama rm dan kemudian menjalankan docker-compose .

Terima kasih!

@fabiomolinar , Pendekatan yang Anda usulkan melanggar beberapa prinsip aplikasi 12 faktor . Jika Anda memasukkan infrastruktur Anda ke dalam container, saya sangat menyarankan agar Anda selalu mematuhinya.

Beberapa masalah yang bisa muncul dari pendekatan Anda

  1. kontainer lambat start-up.
  2. saat menskalakan layanan dengan container, penerapan akan berjalan satu kali untuk setiap instance, berpotensi menyebabkan beberapa masalah konkurensi yang menarik.
  3. lebih sulit untuk mengurutkan log dari 'tugas' dan layanan untuk manajemen dan debugging.

Saya menemukan pendekatan yang saya rekomendasikan kontra-intuitif pada awalnya. Ini telah bekerja dengan baik dalam praktik di lingkungan pengembangan lokal kami di bawah kumpulan buruh pelabuhan, kawanan buruh pelabuhan, dan mesos / maraton. Ini juga efektif mengatasi kurangnya 'onrun'.

Pendekatan yang saya gunakan memang sangat jelek. Saya menggunakannya sebentar hanya untuk menjalankan lingkungan dev saya. Tetapi saya telah mengubahnya untuk menggunakan skrip entrypoint dan perintah at untuk menjalankan skrip setelah server aktif dan berjalan. Sekarang penampung saya berjalan dengan proses yang benar sebagai PID 1 dan merespons semua sinyal dengan benar.

Kami masih membutuhkan ini. Saya tidak dapat menemukan cara, bagaimana saya dapat mengeksekusi rollup database saya setelah berhasil memulai container tanpa membuatnya dalam sekelompok Makefiles.

@ victor-perov membuat penampung lain untuk tugas tersingsing dan menjalankannya sebagai layanan terpisah

Berikut ini beberapa cuplikan dari salah satu proyek kami untuk menampilkan layanan tugas untuk menjalankan migrasi database.

x-task: &task
  # run once deploy policy for tasks
  deploy:
    restart_policy: 
      condition: none
    replicas: 1

service:
  automata-auth-migrate:
    <<: *automata-auth
    <<: *task
    # without the sleep it can't lookup the host postgres.  maybe the command is ran before the network set is complete.
    command: sleep 5 && python /code/manage.py migrate --noinput

Nah, ini adalah tahun keempat diskusi ini diperluas. Jadi izinkan saya menambahkan +1 saya pada kasus penggunaan yang membutuhkan onrun . PS: Seharusnya saya beli popcorn untuk seluruh utas.

Saya juga akan berpikir onrun atau setara (pasca-lari?) Adalah suatu keharusan. Menambahkan skrip wrapper dan melakukan docker exec ke dalam container itu ... jelek.

IMO buruh pelabuhan compose adalah MVP orkestrasi kontainer yang bagus untuk meyakinkan orang bahwa mengelola kontainer itu mudah. Mungkin kita, komunitas, harus menganggapnya dalam "mode pemeliharaan" karena solusi orkestrasi siap produksi (yaitu kubernetes) telah berkembang biak. Jika Anda memiliki fitur lanjutan seperti dependensi penampung, dikombinasikan dengan fitur yang tidak ada seperti "jalankan hal ini setelah penampung habis", nampaknya cocok dengan narasi bahwa laju pengembangan tidak bergerak. Paling tidak, tidak jelas bahwa fitur ini _harus_ dianggap di luar cakupan.

Anda tidak dapat melakukan semuanya dengan mudah dengan Dockerfile. Katakanlah Anda ingin menambahkan skrip Anda sendiri ke sebuah wadah.
Misalnya, ambil container mysql dan coba tambahkan skrip sederhana untuk memanggil API jika terjadi suatu peristiwa.
Anda dapat melakukannya dengan:

  • Mengubah Dockerfile dari mysql dan menambahkan skrip Anda sendiri ke wadah sebelum entrypoint. Anda tidak dapat menambahkan CMD di Dockerfile , karena ini akan menjadi argumen ke ENTRYPOINT .
  • Anda dapat menjalankan penampung lalu menyalin skrip Anda ke penampung yang sedang berjalan dan menjalankannya [ docker cp , docker exec ].

Jadi itulah mengapa saya juga berpikir fitur seperti onrun bermanfaat karena mengubah Dockerfile tidak selalu cukup.

Dump, kenapa ini ditutup? Pertimbangkan situasi, ketika Anda menggunakan gambar buruh pelabuhan resmi, seperti Cassandra dan Anda perlu memuat skema setelah itu dimulai ... Harus menerapkan solusi skrip bash Anda sendiri untuk ini ... ugh, ini jelek

@somebi sepertinya tulis sudah ditutup ...

Hanya dua sen saya: Saya mendarat di sini karena saat ini saya harus mengaktifkan modul Apache secara manual setiap kali saya memulai penampung (SSL tidak diaktifkan secara default di Docker Hub wordpress image). Bukan akhir dunia tetapi berharap untuk menjalankan beberapa perintah setiap kali naik sehingga saya dapat dengan mulus mengambil kontainer ke atas dan ke bawah tanpa harus masuk.

Hanya dua sen saya: Saya mendarat di sini karena saat ini saya harus mengaktifkan modul Apache secara manual setiap kali saya memulai penampung (SSL tidak diaktifkan secara default di Docker Hub wordpress image). Bukan akhir dunia tetapi berharap untuk menjalankan beberapa perintah setiap kali naik sehingga saya dapat dengan mulus mengambil kontainer ke atas dan ke bawah tanpa harus masuk.

Ini bisa dengan mudah diselesaikan jika Anda membangun gambar baru berdasarkan gambar wordpress, yang memiliki modul yang Anda butuhkan diaktifkan. Kemudian gunakan itu sebagai gantinya untuk misalnya sebuah dockerfile:

FROM wordpress:php7.1
RUN a2enmod ssl

Solusi lain adalah mengunduh wordpress Dockerfile dan menambahkan aktivasi modul di dalamnya. Kemudian buat image baru untuk diri Anda sendiri menggunakan docker build. Misalnya ini adalah Dockerfile untuk wordpress 5.2 dengan php 7.1:

wordpress dockerfile

Anda dapat mengaktifkan lebih banyak modul pada baris 63 atau menjalankan genaration ssl.

Semua ini bukanlah kasus yang saya pikir kita bicarakan di sini. Masalahnya adalah membuat kait dinamis dalam siklus hidup kontainer seperti saat mulai berakhir, dll.

Ini akan menjadi tambahan yang bagus untuk menulis galangan!

Jawaban seperti yang ada di utas ini adalah alasan Kubernetes menyimpan "semua" uang yang dihasilkan Docker (teknologi), dan itu bukan hal yang buruk semoga seseorang akan segera membeli Docker (perusahaan) dan mengubah cara proposal / permintaan komunitas diterima / dianalisis ...

Jawaban seperti yang ada di utas ini adalah alasan Kubernetes menyimpan _ "semua" _ mony Docker (teknologi) yang diproduksi, dan itu bukan hal yang buruk semoga seseorang akan segera membeli Docker (perusahaan) dan mengubah cara proposal / permintaan komunitas diterima / dianalisis ...

Saya menulis kritik serupa, tanpa pernyataan ofensif (itu sejalan dengan proyek sumber _open yang tidak sepenuhnya open source yang pengelolanya dengan tegas mengabaikan argumen tanpa alasan lain selain menunjukkan berapa banyak argumen teknis yang mereka miliki_), itu mendapat banyak dukungan , dan pesan itu telah dihapus.

Itu menunjukkan orang sombong macam apa di balik ini.

Ketika komunitas Anda menuntut sesuatu selama 4 tahun dan Anda (Docker) menutup mata, itu menunjukkan bahwa Anda tidak melihat ke arah yang sama dengan mereka: /

Dan sekarang buruh pelabuhan menyerah dan terjual habis.
Karena mereka tidak dapat mendengarkan ... mereka tersesat.

Malu - tapi hei ho.

Sungguh memalukan bahwa hal seperti ini tidak ada. Saya akan sangat senang jika bisa membuat onFailure hooks, yang bisa terjadi ketika health check gagal.

yaitu

services:
  app:
    image: myapp:latest
    hooks:
      onFailure:
        - # Call a monitoring service (from the host machine) to tell it that the service is offline.

Ini akan berguna pada saat aplikasi tidak terikat ke soket / port. Kubernetes mungkin adalah cara yang tepat, tetapi ini adalah perubahan infrastruktur yang cukup besar dan berlebihan untuk lingkungan yang sangat kecil.

Edit:
Untuk menyiasati ini, saya akhirnya memperbarui entrypoint wadah saya untuk "membungkus" fungsi pemantauan. yaitu

# /app/bin/run_with_monitor
#!/bin/bash
set -eE

updateMonitoringSystem() {
 # do something here... This is run from the container, though, unfortunately.
 if [[ $? -eq 1 ]]; then
  # Failed!
 else
  # All is good!
 fi
}

trap 'updateMonitoringSystem' EXIT

$@
# Dockerfile
....
CMD ["/app/bin/run_with_monitor", "./my-app"

Namun, alangkah baiknya melakukan ini _tanpa_ harus memodifikasi gambar.

: man_shrugging: Datang mencari fungsionalitas dasar ini, yang dimiliki pesaing (Kubernetes), dan sebagai gantinya saya menemukan api tempat sampah.

Sungguh memalukan, sekarang saya harus memelihara gambar buruh pelabuhan terpisah untuk pengujian secara lokal.

Selamat tahun baru: roll_eyes:

image

@ LukeStonehm sama di sini. Diperlukan untuk melakukan SATU perintah setelah wadah itu berdiri tetapi diperlakukan dengan sampah panas. Saya benar-benar tidak ingin mengelola gambar dan file buruh pelabuhan saya sendiri ketika gambar resmi membuat saya 90% atau lebih dari sana.

Sejumlah besar program bergantung pada layanan tertentu agar ada saat startup. Misalnya database MySQL atau MongoDB.

Oleh karena itu, tidak ada cara yang masuk akal untuk menggunakan docker-compose dalam kasus ini.

Sebaliknya, pengguna diharapkan untuk:

  • Pelajari cara menulis Dockerfiles (dan pemrograman)
  • Pelajari cara membangun Docker images
  • Buat Dockerfiles mewarisi dari gambar asli, tambahkan kode untuk memastikan wadah menunggu satu sama lain
  • Periksa pembaruan keamanan gambar dasar secara teratur
  • Ubah Dockerfiles secara teratur untuk menerapkan pembaruan
  • Secara teratur buat Docker images dari Dockerfiles

Dan ini menyebalkan karena:

  • Anda membuang banyak waktu untuk mempelajari hal-hal yang mungkin tidak Anda butuhkan
  • Anda secara teratur membuang sumber daya perangkat keras untuk membangun dan menyimpan Docker images sendiri atau bahkan untuk mengunggah / mengunduh (menarik / mendorong) mereka
  • Anda secara teratur membuang waktu untuk menulis Dockerfiles , membangunnya, mengujinya, memperbaikinya, dll ...
  • Anda berpotensi membahayakan keamanan gambar Anda karena Anda tidak tahu apa yang Anda lakukan
  • Anda kehilangan kemampuan untuk menjalankan hanya secara resmi diverifikasi / ditandatangani Docker images

Jika kami melakukan pemeriksaan awal, semua ini tidak diperlukan dan kami cukup mengubah image: mysql:8.0.18 menjadi image: mysql:8.0.19 kapan pun kami mau dan selesai!

Secara realistis inilah yang sedang terjadi di dunia nyata:

  • Orang-orang membuat sendiri Dockerfiles membuat perubahan sehingga mereka dapat bekerja dengan docker-compose
  • Mereka membangun citra mereka sekali
  • Dan jangan menambalnya secara teratur
  • Peretas senang

Dan Anda tidak dapat mengatakan bahwa docker-compose hanya dimaksudkan untuk "melakukan satu hal" karena sudah melakukan hampir semua hal. Termasuk menarik dan membangun gambar yang lebih penting lagi, menentukan dependensi menggunakan properti depends_on . Ini bahkan bukan tentang mengimplementasikan fitur yang benar-benar baru ini hanya tentang meneruskan parameter lain ke docker .

@ binman-buruh pelabuhan @crosbymichael @dmcgowan @ebriney @ehazlett @eunomie @guillaumerose @jeanlaurent @justincormack @lorenrh @manishtomar @olegburov @routelastresort @spencerhcheng @StefanScherer @thaJeztah @tonistiigi @ulyssessouza @aiordache @ chris-nenek yg tua @ndeloof
Harap pertimbangkan kembali fitur ini atau setidaknya mari berdiskusi dengan baik tentang ini.

Teknik task service bekerja cukup baik untuk saya pada saat ini, tetapi memiliki keanehan itu. Kami telah menerapkan pola dalam file tulis kami untuk migrasi dan inisialisasi aplikasi secara ekstensif. tetapi saya setuju bahwa 'depend_on' yang lebih baik yang menunggu healthcheck berhasil atau penyelesaian tugas / keluar yang berhasil akan membuat banyak tugas lebih mudah dan lebih dapat diandalkan.

Ini benar-benar akan menjadi tambahan yang bermanfaat.

Saya pikir perlu ditekankan bahwa Kubernetes memiliki fungsi ini melalui siklus hidup postStart.

k8s! = buruh pelabuhan-menulis. Saluran salah

Maaf karena tidak jelas, tapi maksud saya adalah: Kubernetes mendukung ini, dan karena Kubernetes dan Docker compose memiliki banyak kasus penggunaan / tujuan yang sama, itu akan menjadi argumen untuk membuatnya dalam penulisan. Maaf jika saya kurang jelas.

Kabar baik!!

Saya pikir buruh pelabuhan telah mendengar kami, (tentang masalah ini dan beberapa lainnya). https://www.docker.com/blog/announcing-the-compose-specification/

Mari kita coba garap spesifikasi yang ada untuk memenuhi kebutuhan masyarakat. Kami dapat mencoba menjadikan ini komunitas yang terbuka dan ramah dengan memulai ulang ini.

Kabar baik!!

Saya pikir buruh pelabuhan telah mendengar kami, (tentang masalah ini dan beberapa lainnya). https://www.docker.com/blog/announcing-the-compose-specification/

Mari kita coba garap spesifikasi yang ada untuk memenuhi kebutuhan masyarakat. Kami dapat mencoba menjadikan ini komunitas yang terbuka dan ramah dengan memulai ulang ini.

Apakah sudah ada yang menyarankan perubahan ini? Milis belum tersedia, jadi saya pikir tempat terbaik berikutnya ada di sini: https://github.com/compose-spec/compose-spec

Saya tidak melihat masalah yang menjelaskan masalah ini tetapi tidak yakin apakah itu tempat yang tepat ...

Sunting: Saya membuka masalah di https://github.com/compose-spec/compose-spec/issues/84.

Anda dapat menggunakan HEALTHCHECK untuk melakukan hal lain seperti contoh berikut:

Kode

Dockerfile

FROM ubuntu

COPY healthcheck.sh /healthcheck.sh
RUN chmod a+x /healthcheck.sh

HEALTHCHECK --interval=5s CMD /healthcheck.sh

CMD bash -c 'set -x; set +e; while true; do cat /test.txt; sleep 3; done'

healthcheck.sh

#/usr/bin/env bash

set -e

FIRST_READY_STATUS_FLAG='/tmp/.FIRST_READY_STATUS_FLAG'

# Health check

echo 'Run command to validate the container status HERE'

# On success
if [ ! -f "${FIRST_READY_STATUS_FLAG}" ]; then
  # On first success...
  touch "${FIRST_READY_STATUS_FLAG}"

  # Run ON_RUN on first health check ok
  if [ ! -z "${DOCKER_ON_RUN}" ]; then
    eval "${DOCKER_ON_RUN}"
  fi
fi
  1. Jalankan pemeriksaan _health_.

    • Jika gagal, keluar dari skrip dengan kode keluar 1 .

    • Jika _health check_ ok, skrip akan dilanjutkan.

  2. Jika ini adalah pemeriksaan _health pertama OK_ dan jika variabel lingkungan DOCKER_ON_RUN ada, jalankan.

Contoh

docker-compose.yml

version: "3.7"

services:
  test:
    build:
      context: .
    image: test/on-run
    environment:
      DOCKER_ON_RUN: echo x >> /test.txt

Anda dapat menggunakan variabel lingkungan DOCKER_ON_RUN untuk mengirimkan perintah khusus untuk dijalankan setelah dijalankan.

Hasil eksekusi

docker-compose build
docker-compose up

Keluaran:

Creating network "tmp_default" with the default driver
Creating tmp_test_1 ... done
Attaching to tmp_test_1
test_1  | + set +e
test_1  | + true
test_1  | + cat /test.txt
test_1  | cat: /test.txt: No such file or directory
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | cat: /test.txt: No such file or directory
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
test_1  | + true
test_1  | + cat /test.txt
test_1  | x
test_1  | + sleep 3
  • Anda dapat melihat kesalahan cat: /test.txt: No such file or directory hingga pemeriksaan _health_ siap.
  • Anda hanya dapat melihat satu x di dalam /test.txt setelah dijalankan .

Semoga ini bisa membantu seseorang.

Edit 1

Jika Anda tidak memerlukan pemeriksaan _health_, Anda dapat menggunakan skrip lainnya.

@ reduardo
Terima kasih atas solusi Anda.
Hanya ingin menambahkan, jika Anda perlu menjalankan perintah satu, seperti untuk pembuatan pengguna atau dll, Anda dapat memasang volume untuk touch "${FIRST_READY_STATUS_FLAG}"

Banyak dari solusi ini merupakan solusi yang valid untuk masalah ini. Misalnya membuat skrip entrypoint juga bisa menyelesaikan ini:
ENTRYPOINT ["./entrypoint.sh"]

yang akan menyertakan logika yang lebih kompleks sebelum menjalankan layanan atau proses yang sebenarnya.
Ini masih bukan pengait yang memungkinkan kita memasukkan logika dalam siklus hidup penampung:

  • sebelum membuat
  • sebelum memulai
  • setelah memulai
  • sebelum menghancurkan
  • bahkan setelah menghancurkan
  • dll ...

Saya tahu bahwa tidak semua hal di atas bermakna tetapi saya harap Anda mendapatkan gambarannya karena inilah intinya.
Ini juga bisa dimasukkan dalam docker-compose dengan petunjuk seperti:

lifecycle:
    before_start: "./beforeStartHook.sh"
    after_destroy: "./afterDestroyHook.sh"

atau bahkan seperti itu:

hooks:
    before_destroy: "./beforeDestroyHook.sh"
    before_create: "./fixFsRights.sh"

Saya tidak dapat menimpa file yang membutuhkan izin root menggunakan skrip hook atau pendekatan skrip bootstrap, karena kami memulai container sebagai pengguna non-root

Wow, fungsionalitas dasar seperti itu dan masih belum diterapkan.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat