
Posting ini ditulis atas permintaan pekerja yang secara berkala bertanya tentang "Cara menjalankan aplikasi Illuminate / Symfony / MyOwn Psr7 di buruh pelabuhan." Saya tidak merasa ingin memberikan tautan ke pos yang ditulis sebelumnya , karena pandangan saya tentang cara mengatasi masalah telah sedikit berubah.
Segala sesuatu yang akan ditulis di bawah ini adalah pengalaman subjektif, yang (seperti biasa) tidak mengklaim sebagai satu-satunya keputusan yang tepat, tetapi beberapa pendekatan dan solusi mungkin tampak menarik dan bermanfaat bagi Anda.
Saya juga akan menggunakan Laravel sebagai aplikasi, karena ini paling akrab bagi saya dan cukup luas. Beradaptasi dengan kerangka kerja / komponen berbasis PSR-7 lainnya adalah mungkin, tetapi cerita ini bukan tentang itu.
Menangani kesalahan
Saya ingin memulai dengan apa yang ternyata "bukan praktik terbaik" dalam konteks artikel sebelumnya :
- Kebutuhan untuk mengubah struktur file di repositori
- Menggunakan FPM. Jika kita menginginkan kinerja dari aplikasi kita, maka mungkin salah satu solusi terbaik bahkan pada tahap pemilihan teknologi adalah meninggalkannya demi sesuatu yang lebih cepat dan "disesuaikan" dengan kenyataan bahwa memori mungkin bocor. RoadRunner oleh lachezis ada di sini yang belum pernah ada sebelumnya
- Gambar terpisah dengan sumber dan aset. Terlepas dari kenyataan bahwa menggunakan pendekatan ini, kita dapat menggunakan kembali gambar yang sama untuk membangun perutean yang lebih kompleks dari permintaan masuk (nginx di depan untuk mengembalikan statis; permintaan untuk dinamika dilayani oleh wadah lain di mana volume dilemparkan dengan sumber yang sama - untuk scaling lebih baik) - skema ini telah terbukti agak rumit dalam operasi produk. Dan terlebih lagi, RR dengan sendirinya merender statika, dan jika ada banyak statika (atau sumber daya dapat memuat dan menampilkan konten yang dibuat pengguna) - kami membawanya ke CDN (bundel S3 + CloudFront + CloudFlare berfungsi dengan baik) dan lupakan masalah ini pada prinsipnya
- CI kompleks. Ini menjadi masalah nyata ketika periode "daging bangunan" aktif dimulai pada tahap perakitan dan pengujian otomatis. Seorang pria yang tidak mendukung CI ini sebelumnya, menjadi sangat sulit untuk melakukan perubahan tanpa takut merusak apa pun.
Sekarang, mengetahui masalah apa yang perlu diperbaiki dan dengan pemahaman tentang bagaimana melakukan ini, saya mengusulkan melanjutkan penghapusannya. Himpunan "alat pengembang" tidak berubah - itu adalah docker-ce
, docker-compose
dan Makefile
kuat.
Sebagai hasilnya, kita mendapatkan:
- Wadah mandiri dengan aplikasi tanpa perlu memasang volume tambahan
- Contoh menggunakan git-hooks - kami akan meletakkan dependensi yang diperlukan setelah
git pull
secara otomatis dan melarang mendorong kode jika tes gagal (hook akan disimpan di bawah git, secara alami) - RoadRunner akan menangani permintaan HTTP
- Pengembang masih dapat menjalankan
dd(..)
dan dump(..)
untuk debugging, sementara tidak ada yang macet di browser mereka - Tes dapat dijalankan langsung dari PHPStorm IDE, sementara itu akan dijalankan dalam wadah dengan aplikasi
- CI akan mengumpulkan gambar untuk kami saat menerbitkan tag versi aplikasi baru
- Mari kita ambil aturan ketat untuk memelihara file
CHANGELOG.md
dan ENVIRONMENT.md
Pengenalan visual dari pendekatan baru
Untuk demonstrasi visual, saya akan memecah seluruh proses menjadi beberapa tahap, perubahan di dalamnya akan dibuat sebagai MR terpisah (setelah merger, semua brunch akan tetap di tempatnya masing-masing; referensi ke MR di pos "langkah"). Titik awalnya adalah kerangka Laravel aplikasi yang dibuat menggunakan composer create-project laravel/laravel
:
$ docker run \ --rm -i \ -v "$(pwd):/src" \ -u "$(id -u):$(id -g)" \ composer composer create-project --prefer-dist laravel/laravel \ /src/laravel-in-docker-with-rr "5.8.*"
Langkah pertama adalah mengajarkan aplikasi untuk berjalan di wadah. Untuk melakukan ini, kita membutuhkan Dockerfile
, docker-compose.yml
untuk deskripsi "cara mengangkat dan menautkan kontainer", dan Makefile
untuk mengurangi proses yang sudah disederhanakan menjadi satu atau dua perintah.
Dockerfile
Gambar dasar saya menggunakan php:XXX-alpine
sebagai yang termudah dan berisi apa yang perlu Anda jalankan. Selain itu, semua pembaruan juru bahasa berikutnya dikurangi menjadi sekadar mengubah nilai pada baris ini (memperbarui PHP sekarang lebih mudah dari sebelumnya).
Komposer dan file biner RoadRunner dikirim ke wadah menggunakan multistage dan COPY --from=...
- ini sangat nyaman, dan semua nilai yang terkait dengan versi tidak "tersebar", tetapi berada di awal file. Ini bekerja cepat, dan tanpa ketergantungan pada curl
/ git clone
/ make build
. 512k / roadrunner didukung oleh saya, jika Anda mau - Anda dapat merakit sendiri file biner.
Sebuah cerita menarik terjadi dengan variabel lingkungan PS1
(bertanggung jawab atas prompt di shell) - ternyata Anda dapat menggunakan emoji di dalamnya, dan semuanya bekerja secara lokal, tetapi jika Anda mencoba memulai gambar dengan variabel yang mengandung emoji di, katakanlah, peternak, itu akan macet (di gerombolan semuanya bekerja tanpa masalah).
Di Dockerfile
saya mulai membuat sertifikat SSL yang ditandatangani sendiri untuk menggunakannya untuk permintaan HTTPS yang masuk. Secara alami - tidak ada yang mencegah penggunaan sertifikat "normal".
Saya juga ingin mengatakan tentang:
COPY ./composer.* /app/ RUN set -xe \ && composer install --no-interaction --no-ansi --no-suggest --prefer-dist \ --no-autoloader --no-scripts \ && composer install --no-dev --no-interaction --no-ansi --no-suggest \ --prefer-dist --no-autoloader --no-scripts
Di sini artinya adalah sebagai berikut - file composer.lock
dan composer.json
dikirim dalam lapisan terpisah ke gambar, setelah semua dependensi yang dijelaskan di dalamnya diinstal. Hal ini dilakukan agar selama pembuatan selanjutnya gambar menggunakan --cache-from
, jika komposisi dan versi dependensi yang diinstal tidak berubah, maka composer install
tidak dieksekusi, mengambil lapisan ini dari cache, sehingga menghemat waktu dan lalu lintas pembangunan (terima kasih atas idenya jetexe ).
composer install
dieksekusi dua kali (kedua kalinya dengan --no-dev
) untuk "menghangatkan" cache dependensi dev, sehingga ketika kita meletakkan semua dependensi pada CI untuk menjalankan tes, mereka dimasukkan dari cache komposer, yang sudah ada dalam gambar, dan tidak membentang dari galaksi yang jauh.
Dengan instruksi RUN
terakhir, kami menampilkan versi perangkat lunak yang diinstal dan komposisi modul PHP baik untuk sejarah di build logs dan untuk memastikan bahwa "setidaknya ada dan entah bagaimana mulai."
Saya juga menggunakan Entrypoint saya, karena sebelum memulai aplikasi di suatu tempat di cluster saya benar-benar ingin memeriksa ketersediaan layanan dependen - DB, redis, kelinci dan lain-lain.
Roadrunner
Untuk mengintegrasikan RoadRunner dengan aplikasi Laravel, sebuah paket ditulis yang mengurangi semua integrasi menjadi beberapa perintah dalam shell (dengan docker-compose run app sh
):
$ composer require avto-dev/roadrunner-laravel "^2.0" $ ./artisan vendor:publish --provider='AvtoDev\RoadRunnerLaravel\ServiceProvider' --tag=rr-config
Tambahkan APP_FORCE_HTTPS=true
ke file ./docker/docker-compose.env
, dan tentukan jalur ke sertifikat SSL dalam wadah di .rr*.yaml
.
Agar dapat menggunakan dump(..)
dan dd(..)
dan semuanya akan berfungsi, ada paket lain - avto-dev/stacked-dumper-laravel
. Yang diperlukan hanyalah menambahkan pefix ke pembantu ini, yaitu \dev\dd(..)
dan \dev\dump(..)
masing-masing. Tanpa ini, Anda akan melihat kesalahan formulir:
worker error: invalid data found in the buffer (possible echo)
Setelah semua manipulasi, lakukan docker-compose up -d
dan voila:

Basis data PostgeSQL, redis, dan pekerja RoadRunner berhasil dijalankan dalam wadah.
Seperti yang saya tulis sebelumnya, Makefile adalah item yang sangat diremehkan. Tergantung tujuan, gula sintaksis Anda sendiri, 99% kemungkinan dia sudah berdiri di Linux / mesin pengembangan mac, autocomplete "di luar kotak" - daftar kecil dari keuntungannya.
Menambahkannya ke proyek kami dan melakukan make
tanpa parameter, kita dapat mengamati:

Untuk menjalankan tes unit, kita bisa melakukan make test
, atau mendapatkan shell di dalam wadah dengan aplikasi ( make shell
), jalankan composer phpunit
. Untuk mendapatkan laporan peliputan, cukup buat make test-cover
, dan sebelum menjalankan tes, xdebug dengan dependensinya akan dikirimkan ke wadah dan tes akan diluncurkan (karena prosedur ini tidak sering dilakukan dan bukan oleh CI - solusi ini tampaknya lebih baik daripada menyimpan gambar terpisah dengan semua dev-lotion).
Git hooks
Pengait dalam kasus kami akan memenuhi 2 peran penting - tidak memungkinkan memasukkan kode ke tempat asal yang pengujiannya tidak berhasil; dan secara otomatis menempatkan semua dependensi yang diperlukan jika, menarik perubahan ke mesin Anda, ternyata composer.lock
telah berubah. Di Makefile
, ada target terpisah untuk ini:
cwd = $(shell pwd) git-hooks: ## Install (reinstall) git hooks (required after repository cloning) -rm -f "$(cwd)/.git/hooks/pre-push" "$(cwd)/.git/hooks/pre-commit" "$(cwd)/.git/hooks/post-merge" ln -s "$(cwd)/.gitlab/git-hooks/pre-push.sh" "$(cwd)/.git/hooks/pre-push" ln -s "$(cwd)/.gitlab/git-hooks/pre-commit.sh" "$(cwd)/.git/hooks/pre-commit" ln -s "$(cwd)/.gitlab/git-hooks/post-merge.sh" "$(cwd)/.git/hooks/post-merge"
Melakukan make git-hooks
hanya menghilangkan hook yang ada dan meletakkannya di .gitlab/git-hooks
di tempatnya. Sumber mereka dapat dilihat di tautan ini .
Menjalankan tes dari PhpStorm
Terlepas dari kenyataan bahwa itu cukup sederhana dan nyaman - saya menggunakannya untuk waktu yang lama ./vendor/bin/phpunit --group=foo
daripada hanya menekan hotkey secara langsung saat menulis tes atau kode yang terkait dengannya.
Klik File > Settings > Languages & Frameworks > PHP > CLI interpreter > [...] > [+] > From Docker, Vargant, VM, Remote
. Pilih komposisi Docker , dan nama layanan aplikasi .

Langkah kedua adalah memberi tahu phpunit untuk menggunakan juru bahasa dari wadah: File > Settings > Test frameworks > [+] > PHPUnit by remote interpreter
dan pilih interpreter jarak jauh yang dibuat sebelumnya. Di bidang Path to script
, tentukan /app/vendor/autoload.php
, dan di Path mappings
tentukan direktori root dari proyek yang terpasang di /app
.

Dan sekarang kita dapat menjalankan tes langsung dari IDE menggunakan interpreter di dalam gambar dengan aplikasi, menekan (secara default, Linux) Ctrl + Shift + F10.
Yang tersisa untuk kita lakukan adalah mengotomatiskan proses menjalankan tes dan merakit gambar. Untuk melakukan ini, buat file .gitlab-ci.yml
di direktori root aplikasi, isi dengan konten berikut . Gagasan utama dari konfigurasi ini adalah sesederhana mungkin, tetapi tidak kehilangan fungsionalitas pada saat bersamaan.
Gambar dirakit di setiap makan siang, di setiap komit. Menggunakan --cache-from
merakit gambar setelah komit ulang sangat cepat. Kebutuhan untuk membangun kembali adalah karena pada setiap brunch kita memiliki gambar dengan perubahan yang dibuat sebagai bagian dari brunch ini, dan sebagai hasilnya, tidak ada yang mencegah kita untuk meluncurkannya ke swarm / k8s / etc untuk memastikan "live" bahwa semuanya bekerja, dan berfungsi sebagaimana mestinya bahkan sebelum bergabung dengan master
light.
Setelah perakitan, kami menjalankan tes unit dan memeriksa peluncuran aplikasi dalam wadah, mengirimkan permintaan saat ini ke titik akhir pemeriksaan kesehatan (tindakan ini opsional, tetapi beberapa kali tes ini banyak membantu saya).
Untuk "rilis rilis" - cukup terbitkan tag bentuk vX.XX
(jika Anda masih tetap menggunakan versi semantik - itu akan sangat keren) - CI akan mengumpulkan gambar, menjalankan tes, dan melakukan tindakan yang Anda tentukan dalam deploy to somewhere
.
Jangan lupa dalam pengaturan proyek (jika mungkin) untuk membatasi kemampuan untuk mempublikasikan tag hanya untuk orang yang diizinkan untuk "melepaskan rilis".
CHANGELOG.md
dan ENVIRONMENT.md
Sebelum menerima satu atau yang lain MR, inspektur harus, tanpa gagal, periksa file CHANGELOG.md
dan ENVIRONMENT.md
CHANGELOG.md
ENVIRONMENT.md
. Jika yang pertama lebih dan kurang jelas , maka relatif kedua saya akan memberikan penjelasan. File ini digunakan untuk menjelaskan semua variabel lingkungan yang ditampung oleh aplikasi. Yaitu jika pengembang menambahkan atau menghapus dukungan untuk satu atau variabel lingkungan lain, ini harus tercermin dalam file ini. Dan pada saat pertanyaan "Kami sangat perlu untuk mendefinisikan kembali ini dan itu" muncul - tidak ada yang panik mulai mempelajari dokumentasi atau kode sumber - tetapi melihat dalam satu file. Sangat nyaman
Kesimpulan
Pada artikel ini, kami memeriksa proses yang agak tidak menyakitkan untuk mentransfer pengembangan aplikasi dan meluncurkan ke lingkungan Docker, RoadRunner yang terintegrasi, dan menggunakan skrip CI sederhana yang mengotomatiskan perakitan dan pengujian gambar dengan aplikasi kami.
Setelah mengkloning repositori, para pengembang harus melakukan make git-hooks && make install && make up
dan mulai menulis kode yang berguna. Kamerad * ops-am - mengambil gambar dengan tag yang diinginkan dan menggulungnya pada kelompok mereka.
Secara alami - skema ini juga disederhanakan, dan pada proyek "pertempuran" saya membuat lebih banyak, tetapi jika pendekatan yang dijelaskan dalam artikel membantu seseorang, saya akan tahu bahwa saya membuang-buang waktu.