Bagaimana cara menyebarkan dengan benar ketika menggunakan sakelar pengembangan / produksi Komposer?

180

Komposer memiliki opsi untuk memuat beberapa dependensi hanya saat sedang dalam pengembangan, sehingga alat tidak akan diinstal dalam produksi (pada server langsung). Ini (secara teori) sangat berguna untuk skrip yang hanya masuk akal dalam pengembangan, seperti tes, alat data palsu, debugger, dll.

Cara untuk pergi adalah menambahkan require-devblok tambahan dengan alat yang Anda butuhkan di dev:

"require-dev": {
    "codeception/codeception": "1.6.0.3"
}

dan kemudian (secara teoritis) memuat dependensi ini melalui

composer install --dev

Masalah & pertanyaan:

Komposer telah mengubah perilaku installdan updatesecara dramatis pada tahun 2013, require-dev-dependensi sekarang diinstal secara default (!), Jangan ragu untuk membuat komposer. Json dengan require-devblok dan melakukan composer installmereproduksi.

Sebagai cara yang paling diterima untuk menyebarkan adalah dengan mendorong komposer. mengunci (yang menahan pengaturan komposer Anda saat ini) dan kemudian melakukan composer installpada server produksi, ini juga akan menginstal hal pengembangan.

Apa cara yang benar untuk menggunakan ini tanpa menginstal dependensi -ev?

Catatan: Saya mencoba membuat Tanya Jawab kan di sini untuk memperjelas penyebaran Komposer yang aneh. Jangan ragu untuk mengedit pertanyaan ini.

Sliq
sumber
@all: Tidak tahu di mana hadiahnya :( Saya akan memulai pendekatan lain.
Sliq
1
Jika Anda tidak secara aktif menghadiahkannya, dan tidak ada jawaban yang diterima atau mendapat cukup banyak suara, tidak ada yang mendapat hadiah.
Sven
2
Saya pribadi tidak menyukai pendekatan ini sama sekali. The composer.locktidak boleh ditambahkan ke repo Git, tidak pernah. Pendekatan yang tepat adalah dengan menggunakan pembaruan komposer pada pementasan dan kemudian menyinkronkan file menjadi produksi (jika semuanya berfungsi, tentu saja). Pementasan harus merupakan salinan tepat dari lingkungan produksi. composer.lockharus menjadi bagian dari .gitignore.
kata benda
6
composer.lock pasti termasuk dalam CSV Anda !!! Bagaimana lagi Anda memastikan semua orang menggunakan versi yang sama ?? Jadi, JANGAN PERNAH mengecualikan komposer. Buka dari CSV Anda !!!
Tobias Gaertner
3
@TobiasGaertner Saya pikir maksud Anda VCS (perangkat lunak kontrol versi), tetapi Anda benar dan sejalan dengan rekomendasi resmi proyek .
Xiong Chiamiov

Jawaban:

327

Mengapa

Ada IMHO alasan bagus mengapa Komposer akan menggunakan --devflag secara default (saat menginstal dan memperbarui) saat ini. Komposer sebagian besar dijalankan dalam skenario di mana ini perilaku yang diinginkan:

Alur kerja Komposer dasar adalah sebagai berikut:

  • Proyek baru dimulai composer.phar install --dev:, file json dan kunci dikomit ke VCS.
  • Pengembang lain mulai mengerjakan proyek: checkout VCS dan composer.phar install --dev.
  • Pengembang menambahkan dependancies:, composer.phar require <package>tambahkan --devjika Anda ingin paket di require-devbagian (dan komit).
  • Lainnya mengikuti: (checkout dan) composer.phar install --dev.
  • Pengembang menginginkan versi dependensi yang lebih baru: composer.phar update --dev <package>(dan melakukan).
  • Lainnya mengikuti: (checkout dan) composer.phar install --dev.
  • Proyek dikerahkan: composer.phar install --no-dev

Seperti yang Anda lihat, --devflag digunakan (jauh) lebih dari --no-devflag, terutama ketika jumlah pengembang yang bekerja pada proyek bertambah.

Penempatan produksi

Apa cara yang benar untuk menyebarkan ini tanpa menginstal dependensi "dev"?

Nah, file composer.jsondan composer.lockharus dikomit ke VCS. Jangan hilangkan composer.lockkarena mengandung informasi penting tentang versi paket yang harus digunakan.

Saat melakukan penyebaran produksi, Anda dapat meneruskan --no-devbendera ke Komposer:

composer.phar install --no-dev

The composer.lockFile mungkin berisi informasi tentang dev-paket. Ini tidak masalah. The --no-devbendera akan memastikan mereka dev-paket tidak diinstal.

Ketika saya mengatakan "penyebaran produksi", maksud saya penyebaran yang ditujukan untuk digunakan dalam produksi. Saya tidak berdebat apakah composer.phar installharus dilakukan pada server produksi, atau pada server pementasan di mana hal-hal dapat ditinjau. Itu bukan cakupan dari jawaban ini. Saya hanya menunjukkan bagaimana composer.phar installtanpa menginstal dependensi "dev".

Menyimpang dari topik

The --optimize-autoloaderflag mungkin juga diinginkan pada produksi (menghasilkan kelas-peta yang akan mempercepat autoloading dalam aplikasi Anda):

composer.phar install --no-dev --optimize-autoloader

Atau ketika penyebaran otomatis dilakukan:

composer.phar install --no-ansi --no-dev --no-interaction --no-plugins --no-progress --no-scripts --no-suggest --optimize-autoloader

Jika basis kode Anda mendukung, Anda bisa menukar --optimize-autoloaderuntuk --classmap-authoritative. Info lebih lanjut di sini

Jasper N. Brouwer
sumber
5
Saya setuju dengan sebagian besar dari apa yang dikatakan dengan satu pengecualian. "komposer instal --no-dev" harus dijalankan hanya dalam lingkungan pementasan dan lingkungan itu harus dianggap tidak dapat diubah. Saya tidak ingin ada ketergantungan yang diunduh langsung di server produksi saya dan tanpa melalui pratinjau / pementasan. Itu hanya sedikit ekstra kehati-hatian.
Scalable
3
@Scalable: Meskipun saya setuju dengan Anda (dan Sven membahas hal ini dengan baik dalam jawabannya), itu bukan cakupan jawaban saya, dan bukan yang saya maksud dengan "penyebaran produksi". Saya telah menambahkan paragraf untuk memperjelasnya.
Jasper N. Brouwer
5
Sebenarnya saya pikir defaultnya adalah opsi yang tidak terlalu berbahaya. Membuat --dev sebagai default dan tidak sengaja melakukan pemasangan komposer dalam produksi bisa berakibat fatal.
Hector Ordonez
3
Poin bagus di --optimize-autoloader. Pertimbangkan juga --classmap-authoritative- Dari dokumentasi di sini getcomposer.org/doc/03-cli.md Anda dapat melihat ini: "Hanya memuat kelas dari classmap saja. Secara implisit memungkinkan --optimize-autoloader" sehingga Anda dapat menggunakan jika Anda tahu kelasnya " there ", yang mungkin harus terjadi di lingkungan prod Anda kecuali Anda menghasilkan kelas secara dinamis.
Xavi Montero
6
Jawaban yang bagus, saya sarankan menambahkan optimize-autoloaderlangsung di composer.json:{"config": { "optimize-autoloader": true } }
Yvan
79

Sebenarnya, saya akan sangat menyarankan MELAWAN menginstal dependensi pada server produksi.

Rekomendasi saya adalah untuk checkout kode pada mesin penyebaran, instal dependensi sesuai kebutuhan (ini termasuk TIDAK menginstal dependensi dev jika kode masuk ke produksi), dan kemudian pindahkan semua file ke mesin target.

Mengapa?

  • di hosting bersama, Anda mungkin tidak bisa sampai ke baris perintah
  • bahkan jika Anda melakukannya, PHP mungkin dibatasi di sana dalam hal perintah, memori atau akses jaringan
  • alat CLI repositori (Git, Svn) cenderung tidak diinstal, yang akan gagal jika file kunci Anda telah mencatat ketergantungan untuk checkout komit tertentu daripada mengunduh yang komit sebagai ZIP (Anda menggunakan --prefer-source, atau Composer telah tidak ada cara lain untuk mendapatkan versi itu)
  • jika mesin produksi Anda lebih seperti server uji kecil (pikirkan contoh mikro Amazon EC2) mungkin bahkan tidak cukup memori yang dipasang untuk menjalankan composer install
  • sementara komposer mencoba untuk tidak merusak barang-barang, bagaimana perasaan Anda tentang mengakhiri dengan situs web produksi yang rusak sebagian karena beberapa ketergantungan acak tidak dapat dimuat selama tahap pemasangan komposer

Singkat cerita: Gunakan Komposer di lingkungan yang dapat Anda kendalikan. Mesin pengembangan Anda memenuhi syarat karena Anda sudah memiliki semua hal yang diperlukan untuk mengoperasikan Komposer.

Apa cara yang benar untuk menggunakan ini tanpa menginstal dependensi -ev?

Perintah untuk digunakan adalah

composer install --no-dev

Ini akan bekerja di lingkungan apa pun, baik itu server produksi itu sendiri, atau mesin penyebaran, atau mesin pengembangan yang seharusnya melakukan pemeriksaan terakhir untuk menemukan apakah persyaratan dev salah digunakan untuk perangkat lunak yang sebenarnya.

Perintah tidak akan menginstal, atau secara aktif menghapus, persyaratan dev yang dinyatakan dalam file composer.lock.

Jika Anda tidak keberatan menggunakan komponen perangkat lunak pengembangan pada server produksi, menjalankan composer installakan melakukan pekerjaan yang sama, tetapi hanya meningkatkan jumlah byte yang dipindahkan, dan juga membuat deklarasi autoloader yang lebih besar.

Sven
sumber
14
Alur kerja yang menarik, tapi ada besar con : Repositories tidak boleh mengandung folder vendor / isi sendiri (pernyataan resmi di laman Composer), sehingga mereka tidak akan pernah langsung didorong ke produksi dalam penyebaran berbasis git (yang merupakan afaik standar umum, koreksi saya jika saya salah). Jadi pada dasarnya solusi di atas hanya bekerja dengan penyebaran FTP "old-school" !? Tolong mari kita bahas lebih lanjut ini ...
Sliq
17
Alur kerja saya yang disarankan tidak termasuk mendorong kode melalui GIT ke server produksi. Bahkan, saya akan merekomendasikan menentang, karena hal itu akan memaksa Anda untuk menginstal ketergantungan Composer pada server produksi, yang dapat memunculkan sejumlah masalah. Jika Anda ingin penyebaran Anda berjalan dengan lancar, Anda harus mengumpulkan semua kode yang diperlukan untuk menjalankan aplikasi sebelum Anda menghancurkan versi saat ini dan menggantinya. Tidak suka FTP? RSync via SSH, lalu alihkan versi dengan membalik symlink. Tetapi Anda juga dapat mendorong, checkout, dan menginstal komposer di prod jika Anda mau.
Sven
2
@Panique: Saya baru saja melihat bagian dari komentar Anda dan saya harus menjawab: "mendorong produksi dalam penyebaran berbasis git (yang merupakan standar umum afaik, koreksi saya jika saya salah)" - Tidak, ini bukan standar umum. Itu hanya satu cara untuk melakukannya.
Sven
1
Tim yang saya ikuti telah memasukkan ini ke dalam alur kerja mereka dengan sukses besar. Kami memiliki mesin build (Jenkins, tentu saja) yang: 1) memeriksa dari SC 2) menjalankan pemasangan / pembaruan komposer 3) menjalankan pengujian unit 4) menghapus dependensi dev 5) menghasilkan file phar ( app-1.34.phardll). Ada mekanisme terpisah yang diberitahukan dan memutuskan kapan harus mengambil file itu, ke mana harus mentransfernya, dan kemudian apa yang harus dilakukan dengannya. Beberapa tim memilih untuk membongkar phar begitu ada di server dan beberapa tim menjalankannya apa adanya. Ini meminjamkan banyak kepercayaan pada stabilitas dan reproduktifitas dari penyebaran kami.
Josh Johnson
3
Saya setuju 100% dengan jawaban ini. Komposer tidak boleh diinstal pada server penyebaran, atau git. Continuous Deployment / Intergration server seharusnya mengelola sumber dan dependensi mengambil: git pull> install komposer> deploy
Eric MORAND
4

Sekarang require-devdiaktifkan secara default, untuk pengembangan lokal Anda dapat melakukan composer installdan composer updatetanpa--dev opsi.

Saat Anda ingin menggunakan produksi, Anda harus memastikan composer.locktidak memiliki paket yang berasalrequire-dev .

Anda dapat melakukannya dengan

composer update --no-dev

Setelah Anda menguji secara lokal dengan --no-devAnda dapat menggunakan semuanya untuk produksi dan menginstal berdasarkan composer.lock. Anda perlu --no-devopsi lagi di sini, jika komposer akan mengatakan "File kunci tidak berisi informasi dev-kebutuhan" .

composer install --no-dev

Catatan: Hati-hati dengan apa pun yang berpotensi menimbulkan perbedaan antara dev dan produksi! Saya biasanya mencoba untuk menghindari keharusan-dev sedapat mungkin, karena menyertakan alat dev bukanlah overhead yang besar.

dave1010
sumber
1
Ini sebenarnya salah dalam detailnya. Tidak perlu memeriksa composer.lockdependensi dev. Anda cukup menjalankan composer install --no-dev, dan Anda hanya akan menginstal dependensi reguler - pada kenyataannya, Komposer juga akan menghapus dependensi dev apa pun di langkah ini.
Sven
Jika lokal saya composer.lockmemiliki dependensi dev di dalamnya (dan berpotensi mempengaruhi versi paket non-dev) maka saya ingin memperbaruinya untuk mencerminkan bagaimana itu akan di produksi. Ini juga memaksa Anda untuk menjalankan composer install --no-devproduksi, seperti yang composer installakan terjadi kesalahan. Secara teknis saya pikir Anda benar; ini tidak diperlukan, tetapi ini adalah tingkat keamanan ekstra, yang saya suka.
dave1010
Oke, skenario demo: Aplikasi Anda membutuhkan dev/tooldan prod/lib:~1.0. Prod / lib terbaru adalah 1.3, tetapi dev / tool juga membutuhkan prod/lib:1.1.*. Hasil: Anda akan menginstal versi 1.1.9 (terbaru dari cabang 1.1.x) dan menggunakannya selama pengembangan Anda. Saya akan mengatakan itu TIDAK aman untuk hanya memperbarui --no-dev, sehingga termasuk prod / lib 1.3 terbaru dan menganggap semuanya berfungsi tanpa pengujian. Dan mungkin pengujian tidak mungkin karena kurangnya dev / tool. Saya akan berasumsi bahwa karena dev / tool tidak diperlukan dalam produksi, itu tidak boleh diluncurkan, tetapi perangkat lunak harus menggunakan prod / lib 1.1.9 lalu.
Sven
Jika Anda menggunakan --no-devmaka Anda perlu mengujinya secara lokal, seperti yang saya sebutkan dalam jawabannya. Saya masih merekomendasikan untuk tidak menggunakan --no-devsama sekali.
dave1010
Jadi pada dasarnya Anda menyarankan ini:, composer updatelalu lakukan pengembangan, lalu lakukan composer update --no-dev, lalu lakukan pengujian rilis, lalu dorong produksi dan lakukan composer install --no-dev. Dua masalah: 1. Saya tidak bisa menguji rilis tanpa dependensi dev, dan 2. Saya tidak bisa menginstal dengan misalnya Git dalam produksi.
Sven
3

Pada server produksi saya mengganti nama vendormenjadi vendor-<datetime>, dan selama penyebaran akan memiliki dua dir vendor.

Cookie HTTP menyebabkan sistem saya memilih vendor baru autoload.php , dan setelah pengujian saya melakukan pergantian atom / instan sepenuhnya di antara mereka untuk menonaktifkan dir vendor lama untuk semua permintaan di masa depan, kemudian saya menghapus dir sebelumnya beberapa hari kemudian.

Ini menghindari masalah yang disebabkan oleh cache sistem file yang saya gunakan di apache / php, dan juga memungkinkan kode PHP aktif untuk terus menggunakan dir vendor sebelumnya.


Meskipun ada jawaban lain yang merekomendasikan hal itu, saya secara pribadi berlari composer install di server, karena ini lebih cepat daripada rsync dari area stage saya (VM di laptop saya).

Saya menggunakan --no-dev --no-scripts --optimize-autoloader. Anda harus membaca dokumen untuk masing-masing untuk memeriksa apakah ini sesuai pada lingkungan Anda.

Abhi Beckert
sumber
2

Saya pikir lebih baik mengotomatiskan proses:

Tambahkan file composer.lock di repositori git Anda, pastikan Anda menggunakan composer.phar instal --no-dev ketika Anda rilis, tetapi di mesin dev Anda bisa menggunakan perintah komposer tanpa khawatir, ini tidak akan berlaku untuk produksi, produksi akan mendasarkan ketergantungannya pada file kunci.

Di server Anda checkout versi atau label khusus ini, dan menjalankan semua tes sebelum mengganti aplikasi, jika tes lulus Anda melanjutkan penyebaran.

Jika tes bergantung pada dependensi dev, karena komposer tidak memiliki dependensi cakupan pengujian, solusi yang tidak terlalu bagus dapat menjalankan tes dengan dependensi dev ( pemasangan composer.phar ), hapus pustaka vendor, jalankan komposer.phar install - -tidak lagi, ini akan menggunakan dependensi cache jadi lebih cepat. Tapi itu adalah retasan jika Anda tahu konsep cakupan di alat bangun lain

Otomatiskan ini dan lupakan sisanya, minum bir :-)

PS .: Seperti dalam komentar @Sven di bawah, bukan ide yang baik untuk tidak memeriksa file composer.lock, karena ini akan membuat pekerjaan pemasangan komposer sebagai pembaruan komposer.

Anda dapat melakukan otomatisasi dengan http://deployer.org/ ini adalah alat sederhana.

Giovanni Silva
sumber
2
Tidak melakukan dan memeriksa composer.lockakan membuat composer installtindakan seperti composer update. Jadi, versi yang Anda gunakan bukan versi yang Anda kembangkan. Ini kemungkinan akan menimbulkan masalah (dan lebih lagi mengingat satu-satunya masalah keamanan yang baru saja diselesaikan dengan "ganti" di Komposer). Anda TIDAK PERNAH harus menjalankan composer updatetanpa pengawasan tanpa memverifikasi itu tidak merusak apa pun.
Sven
1
@ Bahkan ini adalah cara yang disarankan dalam komentar yang sama untuk menjalankan tes Unit secara otomatis sebelum penerapan. Tapi Anda benar, lebih baik tetap menyimpan file composer.lock.
Giovanni Silva
Sekarang satu-satunya hal yang harus Anda jelaskan: Bagaimana Anda menjalankan tes di server tanpa dependensi dev seperti PHPUnit?
Sven
Akan sangat bagus, jika dependensi, tes dan penyebaran ditempatkan bersama dalam satu alat, seperti Java Gradle atau SBT atau bahkan Maven (maven tidak begitu baik). Satu alat PHP yang membuat phpunit dan penyebaran komposer bekerja bersama. Atau bahkan sebuah plugin Gradle atau Scala SBT untuk membuat hal-hal ini, karena mereka adalah alat build agnostik, plugin ini bahkan dapat bekerja dengan aset seperti meminimalkan javascript dan menyusun sass, meminimalkan css. Ada yang tahu sesuatu?
Giovanni Silva
1
Tentu saja ini dilakukan di server untuk menguji lingkungan nyata, tetapi tidak langsung di situs vhost, Anda dapat melakukan ini di folder sementara yang terpisah dan memindahkan hasilnya ke vhost ketika berhasil
Giovanni Silva