Mencipta rantaian CI/CD dan mengautomasikan kerja dengan Docker

Saya menulis laman web pertama saya pada akhir 90-an. Pada masa itu ia adalah sangat mudah untuk meletakkan mereka dalam susunan yang berfungsi. Terdapat pelayan Apache pada beberapa pengehosan bersama, anda boleh log masuk ke pelayan ini melalui FTP dengan menulis sesuatu seperti ftp://ftp.example.com. Kemudian anda perlu memasukkan nama dan kata laluan anda dan memuat naik fail ke pelayan. Ada masa yang berbeza, semuanya lebih mudah dahulu daripada sekarang.

Mencipta rantaian CI/CD dan mengautomasikan kerja dengan Docker

Dalam dua dekad sejak itu, semuanya telah banyak berubah. Tapak web telah menjadi lebih kompleks; mereka mesti dipasang sebelum dikeluarkan ke dalam pengeluaran. Satu pelayan tunggal menjadi banyak pelayan yang berjalan di belakang pengimbang beban, dan penggunaan sistem kawalan versi menjadi perkara biasa.

Untuk projek peribadi saya, saya mempunyai konfigurasi khas. Dan saya tahu bahawa saya memerlukan keupayaan untuk menggunakan tapak dalam pengeluaran dengan hanya melakukan satu tindakan: menulis kod ke cawangan master pada GitHub. Di samping itu, saya tahu bahawa untuk memastikan operasi aplikasi web kecil saya, saya tidak mahu mengurus kluster Kubernetes yang besar, atau menggunakan teknologi Docker Swarm, atau mengekalkan kumpulan pelayan dengan pod, ejen dan pelbagai jenis lain. kerumitan. Untuk mencapai matlamat membuat kerja semudah mungkin, saya perlu membiasakan diri dengan CI/CD.

Jika anda mempunyai projek kecil (dalam kes ini, projek Node.js) dan anda ingin mengetahui cara mengautomasikan penggunaan projek ini, sambil memastikan bahawa apa yang disimpan dalam repositori betul-betul sepadan dengan apa yang berfungsi dalam pengeluaran, maka saya fikir anda mungkin berminat dengan artikel ini.

Prasyarat

Pembaca artikel ini dijangka mempunyai pemahaman asas tentang baris arahan dan menulis skrip Bash. Di samping itu, dia akan memerlukan akaun Travis CI ΠΈ Hab dok.

Objektif

Saya tidak akan mengatakan bahawa artikel ini tanpa syarat boleh dipanggil "tutorial". Ini lebih kepada dokumen di mana saya bercakap tentang perkara yang telah saya pelajari dan menerangkan proses yang sesuai dengan saya untuk menguji dan menggunakan kod kepada pengeluaran, dilakukan dalam satu pas automatik.

Inilah yang akhirnya menjadi aliran kerja saya.

Untuk kod yang diposkan ke mana-mana cawangan repositori kecuali master, tindakan berikut dilakukan:

  • Projek membina Travis CI bermula.
  • Semua ujian unit, penyepaduan dan hujung ke hujung dilakukan.

Hanya untuk kod yang termasuk master, perkara berikut dilakukan:

  • Semua yang disebutkan di atas, ditambah...
  • Membina imej Docker berdasarkan kod, tetapan dan persekitaran semasa.
  • Meletakkan imej ke Docker Hub.
  • Sambungan ke pelayan pengeluaran.
  • Memuat naik imej dari Docker Hub ke pelayan.
  • Menghentikan bekas semasa dan memulakan yang baharu berdasarkan imej baharu.

Jika anda tidak tahu apa-apa tentang Docker, imej dan bekas, jangan risau. Saya akan memberitahu anda semua mengenainya.

Apakah CI/CD?

Singkatan CI/CD bermaksud "integrasi berterusan/penyerahan berterusan."

▍Penyatuan berterusan

Penyepaduan berterusan ialah proses di mana pembangun membuat komitmen kepada repositori kod sumber utama projek (biasanya cawangan master). Pada masa yang sama, kualiti kod dipastikan melalui ujian automatik.

▍Penyerahan berterusan

Penggunaan berterusan ialah penggunaan kod yang kerap dan automatik ke dalam pengeluaran. Bahagian kedua akronim CI/CD kadangkala dinyatakan sebagai "penghantaran berterusan." Ini pada asasnya sama seperti "pengerahan berterusan", tetapi "penghantaran berterusan" membayangkan keperluan untuk mengesahkan perubahan secara manual sebelum memulakan proses penggunaan projek.

Bermula

Aplikasi yang saya gunakan untuk mempelajari semua ini dipanggil Mengambil nota. Ini ialah projek web yang sedang saya usahakan, direka untuk mengambil nota. Pada mulanya saya cuba lakukan JAMStack-projek, atau hanya aplikasi bahagian hadapan tanpa pelayan, untuk memanfaatkan pengehosan standard dan keupayaan penggunaan projek yang ditawarkannya Bersih. Apabila kerumitan aplikasi semakin meningkat, saya perlu mencipta bahagian pelayannya, yang bermaksud bahawa saya perlu merumuskan strategi saya sendiri untuk penyepaduan automatik dan penggunaan automatik projek.

Dalam kes saya, aplikasi itu ialah pelayan Express yang berjalan dalam persekitaran Node.js, menyediakan aplikasi React satu halaman dan menyokong API bahagian pelayan yang selamat. Seni bina ini mengikut strategi yang boleh didapati di diberi Panduan pengesahan tindanan penuh.

Saya berunding dengan kawan, yang merupakan pakar automasi, dan bertanya kepadanya apa yang perlu saya lakukan untuk menjadikan semuanya berfungsi seperti yang saya mahukan. Dia memberi saya idea tentang rupa aliran kerja automatik, yang digariskan dalam bahagian Matlamat artikel ini. Mempunyai matlamat ini bermakna saya perlu memikirkan cara menggunakan Docker.

buruh pelabuhan

Docker ialah alat yang, terima kasih kepada teknologi kontena, membolehkan aplikasi diedarkan, digunakan dan dijalankan dengan mudah dalam persekitaran yang sama, walaupun platform Docker itu sendiri berjalan dalam persekitaran yang berbeza. Pertama, saya perlu mendapatkan tangan saya pada alat baris arahan Docker (CLI). arahan Panduan pemasangan Docker tidak boleh dipanggil sangat jelas dan boleh difahami, tetapi daripada itu anda boleh mengetahui bahawa untuk mengambil langkah pemasangan pertama, anda perlu memuat turun Desktop Docker (untuk Mac atau Windows).

Docker Hub adalah lebih kurang sama dengan GitHub untuk repositori git, atau pendaftaran npm untuk pakej JavaScript. Ini adalah repositori dalam talian untuk imej Docker. Inilah yang disambungkan oleh Docker Desktop.

Jadi, untuk memulakan dengan Docker, anda perlu melakukan dua perkara:

Selepas ini, anda boleh menyemak sama ada CLI Docker berfungsi dengan menjalankan arahan berikut untuk menyemak versi Docker:

docker -v

Seterusnya, log masuk ke Docker Hub dengan memasukkan nama pengguna dan kata laluan anda apabila ditanya:

docker login

Untuk menggunakan Docker, anda mesti memahami konsep imej dan bekas.

▍Imej

Imej ialah sesuatu seperti pelan tindakan yang mengandungi arahan untuk memasang bekas. Ini ialah petikan yang tidak boleh diubah bagi sistem fail dan tetapan aplikasi. Pembangun boleh berkongsi imej dengan mudah.

# Π’Ρ‹Π²ΠΎΠ΄ свСдСний ΠΎΠ±ΠΎ всСх ΠΎΠ±Ρ€Π°Π·Π°Ρ…
docker images

Perintah ini akan mengeluarkan jadual dengan pengepala berikut:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

Seterusnya kita akan melihat beberapa contoh arahan dalam format yang sama - mula-mula terdapat arahan dengan ulasan, dan kemudian contoh apa yang boleh dikeluarkannya.

▍Bekas

Bekas ialah pakej boleh laku yang mengandungi semua yang diperlukan untuk menjalankan aplikasi. Aplikasi dengan pendekatan ini akan sentiasa berfungsi sama, tanpa mengira infrastruktur: dalam persekitaran terpencil dan dalam persekitaran yang sama. Intinya ialah contoh imej yang sama dilancarkan dalam persekitaran yang berbeza.

# ΠŸΠ΅Ρ€Π΅Ρ‡ΠΈΡΠ»Π΅Π½ΠΈΠ΅ всСх ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ΠΎΠ²
docker ps -a
CONTAINER ID     IMAGE     COMMAND     CREATED     STATUS     PORTS     NAMES
---

▍Tag

Tag ialah petunjuk versi tertentu imej.

▍Rujukan pantas kepada arahan Docker

Berikut ialah gambaran keseluruhan beberapa arahan Docker yang biasa digunakan.

Pasukan

Konteks

kesan

binaan buruh pelabuhan

Imej

Membina imej daripada Dockerfile

tag buruh pelabuhan

Imej

Penandaan imej

gambar docker

Imej

Menyenaraikan imej

berlari docker

bekas

Menjalankan bekas berdasarkan imej

tolak buruh pelabuhan

Imej

Memuat naik imej ke pendaftaran

tarik pelabuhan

Imej

Memuatkan imej dari pendaftaran

docker ps

bekas

Menyenaraikan bekas

pemangkasan sistem buruh pelabuhan

Imej/Bekas

Mengalih keluar bekas dan imej yang tidak digunakan

▍Fail Docker

Saya tahu cara menjalankan aplikasi pengeluaran secara tempatan. Saya mempunyai konfigurasi Webpack yang direka untuk membina aplikasi React sedia dibuat. Seterusnya, saya mempunyai arahan yang memulakan pelayan berasaskan Node.js pada port 5000. Ia kelihatan seperti ini:

npm i         # установка зависимостСй
npm run build # сборка React-прилоТСния
npm run start # запуск Node-сСрвСра

Perlu diingatkan bahawa saya tidak mempunyai contoh aplikasi untuk bahan ini. Tetapi di sini, untuk eksperimen, mana-mana aplikasi Node mudah akan dilakukan.

Untuk menggunakan bekas, anda perlu memberikan arahan kepada Docker. Ini dilakukan melalui fail yang dipanggil Dockerfile, terletak dalam direktori akar projek. Fail ini, pada mulanya, kelihatan agak tidak dapat difahami.

Tetapi kandungannya hanya menerangkan, dengan arahan khas, sesuatu yang serupa dengan menyediakan persekitaran kerja. Berikut adalah beberapa arahan ini:

  • DARIPADA β€” Perintah ini memulakan fail. Ia menentukan imej asas di mana bekas itu dibina.
  • SALINAN β€” Menyalin fail daripada sumber tempatan ke bekas.
  • WORKDIR β€” Menetapkan direktori kerja untuk arahan berikut.
  • RUN - Jalankan arahan.
  • DEDAHKAN β€” Tetapan port.
  • ENTRYPOINT - Petunjuk arahan yang akan dilaksanakan.

Dockerfile mungkin kelihatan seperti ini:

# Π—Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ Π±Π°Π·ΠΎΠ²Ρ‹ΠΉ ΠΎΠ±Ρ€Π°Π·
FROM node:12-alpine

# Π‘ΠΊΠΎΠΏΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Ρ„Π°ΠΉΠ»Ρ‹ ΠΈΠ· Ρ‚Π΅ΠΊΡƒΡ‰Π΅ΠΉ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ Π² Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΡŽ app/
COPY . app/

# Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ app/ Π² Ρ€ΠΎΠ»ΠΈ Ρ€Π°Π±ΠΎΡ‡Π΅ΠΉ Π΄ΠΈΡ€Π΅ΠΊΡ‚ΠΎΡ€ΠΈΠΈ
WORKDIR app/

# Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ зависимости (ΠΊΠΎΠΌΠ°Π½Π΄Π° npm ci ΠΏΠΎΡ…ΠΎΠΆΠ° npm i, Π½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… сборок)
RUN npm ci --only-production

# Π‘ΠΎΠ±Ρ€Π°Ρ‚ΡŒ клиСнтскоС React-ΠΏΡ€ΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ для ΠΏΡ€ΠΎΠ΄Π°ΠΊΡˆΠ½Π°
RUN npm run build

# ΠŸΡ€ΠΎΡΠ»ΡƒΡˆΠΈΠ²Π°Ρ‚ΡŒ ΡƒΠΊΠ°Π·Π°Π½Π½Ρ‹ΠΉ ΠΏΠΎΡ€Ρ‚
EXPOSE 5000

# Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Node-сСрвСр
ENTRYPOINT npm run start

Bergantung pada imej asas yang anda pilih, anda mungkin perlu memasang kebergantungan tambahan. Hakikatnya ialah beberapa imej asas (seperti Node Alpine Linux) dicipta dengan matlamat menjadikannya padat yang mungkin. Akibatnya, mereka mungkin tidak mempunyai beberapa program yang anda harapkan.

▍Membina, menandai dan menjalankan bekas

Pemasangan tempatan dan pelancaran kontena adalah selepas kami ada Dockerfile, tugasnya agak mudah. Sebelum anda menolak imej ke Docker Hub, anda perlu mengujinya secara setempat.

▍Perhimpunan

Mula-mula anda perlu mengumpul imej, menyatakan nama dan, secara pilihan, teg (jika teg tidak ditentukan, sistem akan memberikan teg kepada imej secara automatik latest).

# Π‘Π±ΠΎΡ€ΠΊΠ° ΠΎΠ±Ρ€Π°Π·Π°
docker build -t <image>:<tag> .

Selepas menjalankan arahan ini, anda boleh menonton Docker membina imej.

Sending build context to Docker daemon   2.88MB
Step 1/9 : FROM node:12-alpine
 ---> ...Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ этапов сборки...
Successfully built 123456789123
Successfully tagged <image>:<tag>

Binaan mungkin mengambil masa beberapa minit - semuanya bergantung pada bilangan kebergantungan yang anda miliki. Setelah binaan selesai, anda boleh menjalankan arahan docker images dan lihat penerangan imej baharu anda.

REPOSITORY          TAG               IMAGE ID            CREATED              SIZE
<image>             latest            123456789123        About a minute ago   x.xxGB

▍Lancarkan

Imej telah dibuat. Ini bermakna anda boleh menjalankan bekas berdasarkannya. Kerana saya mahu dapat mengakses aplikasi yang berjalan dalam bekas di localhost:5000, saya, di sebelah kiri pasangan itu 5000:5000 dalam arahan seterusnya yang dipasang 5000. Di sebelah kanan ialah pelabuhan kontena.

# Запуск с использованиСм локального ΠΏΠΎΡ€Ρ‚Π° 5000 ΠΈ ΠΏΠΎΡ€Ρ‚Π° ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π° 5000
docker run -p 5000:5000 <image>:<tag>

Sekarang bekas itu dibuat dan berjalan, anda boleh menggunakan arahan docker ps untuk melihat maklumat tentang bekas ini (atau anda boleh menggunakan command docker ps -a, yang memaparkan maklumat tentang semua bekas, bukan hanya yang sedang dijalankan).

CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS                      PORTS                    NAMES
987654321234        <image>             "/bin/sh -c 'npm run…"   6 seconds ago        Up 6 seconds                0.0.0.0:5000->5000/tcp   stoic_darwin

Jika anda sekarang pergi ke alamat localhost:5000 β€” anda boleh melihat halaman aplikasi yang sedang berjalan yang kelihatan sama persis dengan halaman aplikasi yang berjalan dalam persekitaran pengeluaran.

▍Tag dan penerbitan

Untuk menggunakan salah satu imej yang dicipta pada pelayan pengeluaran, kita perlu memuat turun imej ini daripada Docker Hub. Ini bermakna anda perlu membuat repositori untuk projek di Docker Hub terlebih dahulu. Selepas ini, kita akan mempunyai tempat di mana kita boleh menghantar gambar. Imej itu perlu dinamakan semula supaya namanya bermula dengan nama pengguna Docker Hub kami. Ini harus diikuti dengan nama repositori. Mana-mana tag boleh diletakkan di hujung nama. Di bawah ialah contoh menamakan imej menggunakan skema ini.

Kini anda boleh membina imej dengan nama baharu dan menjalankan arahan docker push untuk menolaknya ke repositori Docker Hub.

docker build -t <username>/<repository>:<tag> .
docker tag <username>/<repository>:<tag> <username>/<repository>:latest
docker push <username>/<repository>:<tag>

# На ΠΏΡ€Π°ΠΊΡ‚ΠΈΠΊΠ΅ это ΠΌΠΎΠΆΠ΅Ρ‚ Π²Ρ‹Π³Π»ΡΠ΄Π΅Ρ‚ΡŒ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, Ρ‚Π°ΠΊ:
docker build -t user/app:v1.0.0 .
docker tag user/app:v1.0.0 user/app:latest
docker push user/app:v1.0.0

Jika semuanya berjalan lancar, imej itu akan tersedia di Docker Hub dan boleh dimuat naik dengan mudah ke pelayan atau dipindahkan ke pembangun lain.

Langkah seterusnya

Pada masa ini kami telah mengesahkan bahawa aplikasi itu, dalam bentuk bekas Docker, berjalan secara tempatan. Kami telah memuat naik bekas ke Docker Hub. Semua ini bermakna kami telah mencapai kemajuan yang sangat baik ke arah matlamat kami. Sekarang kita perlu menyelesaikan dua lagi soalan:

  • Menyediakan alat CI untuk menguji dan menggunakan kod.
  • Menyediakan pelayan pengeluaran supaya ia boleh memuat turun dan menjalankan kod kami.

Dalam kes kami, kami menggunakan Travis CI. Sebagai pelayan - DitigalOcean.

Perlu diingatkan bahawa di sini anda boleh menggunakan gabungan perkhidmatan yang lain. Sebagai contoh, bukannya Travis CI, anda boleh menggunakan CircleCI atau Tindakan Github. Dan bukannya DigitalOcean - AWS atau Linode.

Kami memutuskan untuk bekerjasama dengan Travis CI, dan saya sudah mempunyai sesuatu yang dikonfigurasikan dalam perkhidmatan ini. Oleh itu, sekarang saya akan bercakap secara ringkas tentang cara menyediakannya untuk bekerja.

Travis CI

Travis CI ialah alat untuk menguji dan menggunakan kod. Saya tidak mahu pergi ke selok-belok menubuhkan Travis CI, kerana setiap projek adalah unik, dan ini tidak akan membawa banyak manfaat. Tetapi saya akan membincangkan perkara asas untuk memulakan anda jika anda memutuskan untuk menggunakan Travis CI. Sama ada anda memilih Travis CI, CircleCI, Jenkins atau sesuatu yang lain, kaedah konfigurasi yang serupa akan digunakan di mana-mana sahaja.

Untuk bermula dengan Travis CI, pergi ke laman web projek dan buat akaun. Kemudian integrasikan Travis CI dengan akaun GitHub anda. Apabila menyediakan sistem, anda perlu menentukan repositori yang anda mahu mengautomasikan kerja dan membolehkan akses kepadanya. (Saya menggunakan GitHub, tetapi saya pasti Travis CI boleh berintegrasi dengan BitBucket, dan GitLab, dan perkhidmatan lain yang serupa).

Setiap kali Travis CI dimulakan, pelayan dilancarkan, melaksanakan arahan yang dinyatakan dalam fail konfigurasi, termasuk menggunakan cawangan repositori yang sepadan.

▍Kitaran hayat kerja

Fail konfigurasi Travis CI dipanggil .travis.yml dan disimpan dalam direktori akar projek, menyokong konsep peristiwa kitaran hidup tugasan. Peristiwa ini disenaraikan mengikut urutan ia berlaku:

  • apt addons
  • cache components
  • before_install
  • install
  • before_script
  • script
  • before_cache
  • after_success ΠΈΠ»ΠΈ after_failure
  • before_deploy
  • deploy
  • after_deploy
  • after_script

▍Ujian

Dalam fail konfigurasi saya akan mengkonfigurasi pelayan Travis CI tempatan. Saya memilih Node 12 sebagai bahasa dan memberitahu sistem untuk memasang kebergantungan yang diperlukan untuk menggunakan Docker.

Semua yang disenaraikan dalam .travis.yml, akan dilaksanakan apabila semua permintaan tarik dibuat kepada semua cawangan repositori, melainkan dinyatakan sebaliknya. Ini adalah ciri yang berguna kerana ini bermakna kita boleh menguji semua kod yang masuk ke dalam repositori. Ini memberitahu anda jika kod itu sedia untuk ditulis ke cawangan. master, dan sama ada ia akan memecahkan proses pembinaan projek. Dalam konfigurasi global ini, saya memasang semuanya secara setempat, menjalankan pelayan dev Webpack di latar belakang (ini adalah ciri aliran kerja saya) dan menjalankan ujian.

Jika anda mahu repositori anda memaparkan lencana yang menunjukkan liputan ujian, di sini Anda boleh mendapatkan arahan ringkas tentang menggunakan Jest, Travis CI dan Coveralls untuk mengumpul dan memaparkan maklumat ini.

Jadi inilah kandungan fail tersebut .travis.yml:

# Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ язык
language: node_js

# Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ Π²Π΅Ρ€ΡΠΈΡŽ Node.js
node_js:
  - '12'

services:
  # Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΊΠΎΠΌΠ°Π½Π΄Π½ΡƒΡŽ строку Docker
  - docker

install:
  # Π£ΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ зависимости для тСстов
  - npm ci

before_script:
  # Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ сСрвСр ΠΈ ΠΊΠ»ΠΈΠ΅Π½Ρ‚ для тСстов
  - npm run dev &

script:
  # Π—Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ тСсты
  - npm run test

Di sinilah tindakan yang dilakukan untuk semua cawangan repositori dan untuk permintaan tarik berakhir.

▍Pengerahan

Berdasarkan andaian bahawa semua ujian automatik berjaya diselesaikan, kami boleh, yang merupakan pilihan, menggunakan kod ke pelayan pengeluaran. Oleh kerana kami ingin melakukan ini hanya untuk kod dari cawangan master, kami memberi sistem arahan yang sesuai dalam tetapan penggunaan. Sebelum anda cuba menggunakan kod yang akan kami lihat seterusnya dalam projek anda, saya ingin memberi amaran kepada anda bahawa anda mesti mempunyai skrip sebenar yang dipanggil untuk digunakan.

deploy:
  # Π‘ΠΎΠ±Ρ€Π°Ρ‚ΡŒ Docker-ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€ ΠΈ ΠΎΡ‚ΠΏΡ€Π°Π²ΠΈΡ‚ΡŒ Π΅Π³ΠΎ Π½Π° Docker Hub
  provider: script
  script: bash deploy.sh
  on:
    branch: master

Skrip penggunaan menyelesaikan dua masalah:

  • Bina, tag dan hantar imej ke Docker Hub menggunakan alat CI (dalam kes kami, Travis CI).
  • Memuatkan imej pada pelayan, menghentikan bekas lama dan memulakan yang baharu (dalam kes kami, pelayan berjalan pada platform DigitalOcean).

Mula-mula, anda perlu menyediakan proses automatik untuk membina, menandai dan menolak imej ke Docker Hub. Ini semua sangat serupa dengan apa yang telah kami lakukan secara manual, kecuali kami memerlukan strategi untuk menetapkan teg unik pada imej dan mengautomasikan log masuk. Saya menghadapi kesukaran dengan beberapa butiran skrip penggunaan, seperti strategi penandaan, log masuk, pengekodan kunci SSH, penubuhan sambungan SSH. Tetapi nasib baik teman lelaki saya sangat baik dengan bash, seperti dengan banyak perkara lain. Dia membantu saya menulis skrip ini.

Jadi, bahagian pertama skrip ialah memuat naik imej ke Docker Hub. Ini agak mudah dilakukan. Skim penandaan yang saya gunakan melibatkan menggabungkan hash git dan tag git, jika ada. Ini memastikan bahawa teg adalah unik dan memudahkan untuk mengenal pasti pemasangan yang menjadi asasnya. DOCKER_USERNAME ΠΈ DOCKER_PASSWORD ialah pembolehubah persekitaran pengguna yang boleh ditetapkan menggunakan antara muka Travis CI. Travis CI akan memproses data sensitif secara automatik supaya ia tidak jatuh ke tangan yang salah.

Berikut ialah bahagian pertama skrip deploy.sh.

#!/bin/sh
set -e # ΠžΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ скрипт ΠΏΡ€ΠΈ Π½Π°Π»ΠΈΡ‡ΠΈΠΈ ошибок

IMAGE="<username>/<repository>"                             # ΠžΠ±Ρ€Π°Π· Docker
GIT_VERSION=$(git describe --always --abbrev --tags --long) # Git-Ρ…ΡΡˆ ΠΈ Ρ‚Π΅Π³ΠΈ

# Π‘Π±ΠΎΡ€ΠΊΠ° ΠΈ Ρ‚Π΅Π³ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ ΠΎΠ±Ρ€Π°Π·Π°
docker build -t ${IMAGE}:${GIT_VERSION} .
docker tag ${IMAGE}:${GIT_VERSION} ${IMAGE}:latest

# Π’Ρ…ΠΎΠ΄ Π² Docker Hub ΠΈ Π²Ρ‹Π³Ρ€ΡƒΠ·ΠΊΠ° ΠΎΠ±Ρ€Π°Π·Π°
echo "${DOCKER_PASSWORD}" | docker login -u "${DOCKER_USERNAME}" --password-stdin
docker push ${IMAGE}:${GIT_VERSION}

Apakah bahagian kedua skrip bergantung sepenuhnya pada hos yang anda gunakan dan cara sambungan kepadanya diatur. Dalam kes saya, kerana saya menggunakan Lautan Digital, saya menggunakan arahan untuk menyambung ke pelayan doctl. Apabila bekerja dengan AWS, utiliti akan digunakan aws, dan sebagainya.

Menyediakan pelayan tidak begitu sukar. Jadi, saya menyediakan titisan berdasarkan imej asas. Perlu diingatkan bahawa sistem yang saya pilih memerlukan pemasangan Docker manual sekali dan pelancaran Docker manual sekali. Saya menggunakan Ubuntu 18.04 untuk memasang Docker, jadi jika anda juga menggunakan Ubuntu untuk melakukan perkara yang sama, anda hanya boleh mengikuti ini panduan ringkas.

Saya tidak bercakap di sini tentang arahan khusus untuk perkhidmatan, kerana aspek ini boleh berbeza-beza dalam kes yang berbeza. Saya hanya akan memberikan pelan tindakan umum yang akan dilakukan selepas menyambung melalui SSH ke pelayan di mana projek itu akan digunakan:

  • Kita perlu mencari bekas yang sedang berjalan dan menghentikannya.
  • Kemudian anda perlu melancarkan bekas baharu di latar belakang.
  • Anda perlu menetapkan port tempatan pelayan kepada 80 - ini akan membolehkan anda memasuki tapak di alamat seperti example.com, tanpa menyatakan port, dan bukannya menggunakan alamat seperti example.com:5000.
  • Akhir sekali, anda perlu memadam semua bekas dan imej lama.

Berikut adalah sambungan skrip.

# Найти ID Ρ€Π°Π±ΠΎΡ‚Π°ΡŽΡ‰Π΅Π³ΠΎ ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°
CONTAINER_ID=$(docker ps | grep takenote | cut -d" " -f1)

# ΠžΡΡ‚Π°Π½ΠΎΠ²ΠΈΡ‚ΡŒ старый ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€, Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Π½ΠΎΠ²Ρ‹ΠΉ, ΠΎΡ‡ΠΈΡΡ‚ΠΈΡ‚ΡŒ систСму
docker stop ${CONTAINER_ID}
docker run --restart unless-stopped -d -p 80:5000 ${IMAGE}:${GIT_VERSION}
docker system prune -a -f

Beberapa perkara yang perlu diberi perhatian

Ada kemungkinan apabila anda menyambung ke pelayan melalui SSH dari Travis CI, anda akan melihat amaran yang akan menghalang anda daripada meneruskan pemasangan kerana sistem akan menunggu respons pengguna.

The authenticity of host '<hostname> (<IP address>)' can't be established.
RSA key fingerprint is <key fingerprint>.
Are you sure you want to continue connecting (yes/no)?

Saya mengetahui bahawa kunci rentetan boleh dikodkan dalam base64 untuk menyimpannya dalam bentuk yang boleh digunakan dengan mudah dan boleh dipercayai. Pada peringkat pemasangan, anda boleh menyahkod kunci awam dan menulisnya ke fail known_hosts untuk menghilangkan ralat di atas.

echo <public key> | base64 # Π²Ρ‹Π²ΠΎΠ΄ΠΈΡ‚ <ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡, Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π² base64>

Dalam amalan, arahan ini mungkin kelihatan seperti ini:

echo "123.45.67.89 ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSU
GPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3
Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XA
t3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/En
mZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbx
NrRFi9wrf+M7Q== [email protected]" | base64

Dan inilah yang dihasilkannya - rentetan berkod base64:

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

Berikut adalah arahan yang disebutkan di atas

install:
  - echo < ΠΏΡƒΠ±Π»ΠΈΡ‡Π½Ρ‹ΠΉ ΠΊΠ»ΡŽΡ‡, Π·Π°ΠΊΠΎΠ΄ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹ΠΉ Π² base64> | base64 -d >> $HOME/.ssh/known_hosts

Pendekatan yang sama boleh digunakan dengan kunci persendirian apabila membuat sambungan, kerana anda mungkin memerlukan kunci persendirian untuk mengakses pelayan. Apabila bekerja dengan kunci, anda hanya perlu memastikan bahawa ia disimpan dengan selamat dalam pembolehubah persekitaran Travis CI dan ia tidak dipaparkan di mana-mana.

Perkara lain yang perlu diambil perhatian ialah anda mungkin perlu menjalankan keseluruhan skrip penggunaan sebagai satu baris, contohnya - dengan doctl. Ini mungkin memerlukan sedikit usaha tambahan.

doctl compute ssh <droplet> --ssh-command "всС ΠΊΠΎΠΌΠ°Π½Π΄Ρ‹ Π±ΡƒΠ΄ΡƒΡ‚ здСсь && здСсь"

TLS/SSL dan Pengimbangan Beban

Selepas saya melakukan semua yang dinyatakan di atas, masalah terakhir yang saya hadapi ialah pelayan tidak mempunyai SSL. Memandangkan saya menggunakan pelayan Node.js, untuk memaksa untuk bekerja proksi terbalik Nginx dan Let's Encrypt, anda perlu bermain-main banyak.

Saya benar-benar tidak mahu melakukan semua konfigurasi SSL ini secara manual, jadi saya hanya mencipta pengimbang beban dan merekodkan butirannya dalam DNS. Dalam kes DigitalOcean, sebagai contoh, mencipta sijil yang ditandatangani sendiri yang diperbaharui secara automatik pada pengimbang beban adalah prosedur yang mudah, percuma dan pantas. Pendekatan ini mempunyai faedah tambahan yang menjadikannya sangat mudah untuk menyediakan SSL pada berbilang pelayan yang berjalan di belakang pengimbang beban jika diperlukan. Ini membolehkan pelayan sendiri tidak "berfikir" tentang SSL sama sekali, tetapi pada masa yang sama menggunakan port seperti biasa 80. Jadi menyediakan SSL pada pengimbang beban adalah lebih mudah dan lebih mudah daripada kaedah alternatif untuk menyediakan SSL.

Kini anda boleh menutup semua port pada pelayan yang menerima sambungan masuk - kecuali port 80, digunakan untuk berkomunikasi dengan pengimbang beban, dan port 22 untuk SSH. Akibatnya, percubaan untuk mengakses pelayan secara terus pada mana-mana port selain daripada kedua-dua port ini akan gagal.

Keputusan

Selepas saya melakukan semua yang saya bincangkan dalam bahan ini, platform Docker mahupun konsep rantaian CI/CD automatik tidak menakutkan saya lagi. Saya dapat menyediakan rantaian penyepaduan berterusan, di mana kod itu diuji sebelum ia dikeluarkan dan kod itu digunakan secara automatik pada pelayan. Ini semua masih agak baru kepada saya, dan saya pasti ada cara untuk meningkatkan aliran kerja automatik saya dan menjadikannya lebih cekap. Jadi jika anda mempunyai sebarang idea tentang perkara ini, sila beritahu saya. saya tahu. Saya harap artikel ini telah membantu anda dalam usaha anda. Saya ingin percaya bahawa selepas membacanya, anda belajar sebanyak yang saya pelajari sambil memikirkan semua yang saya bincangkan di dalamnya.

PS Dalam kami pasaran ada gambar buruh pelabuhan, yang boleh dipasang dalam satu klik. Anda boleh menyemak operasi bekas di VPS. Semua pelanggan baharu diberi 3 hari ujian secara percuma.

Pembaca yang dihormati! Adakah anda menggunakan teknologi CI/CD dalam projek anda?

Mencipta rantaian CI/CD dan mengautomasikan kerja dengan Docker

Sumber: www.habr.com

Tambah komen