Membuat rantai CI/CD dan mengotomatiskan pekerjaan dengan Docker

Saya menulis situs web pertama saya di akhir tahun 90an. Saat itu sangat mudah untuk membuat mereka berfungsi. Ada server Apache di beberapa shared hosting, Anda dapat masuk ke server ini melalui FTP dengan menulis sesuatu seperti ftp://ftp.example.com. Kemudian Anda harus memasukkan nama dan kata sandi Anda dan mengunggah file ke server. Ada waktu yang berbeda, semuanya lebih sederhana dari sekarang.

Membuat rantai CI/CD dan mengotomatiskan pekerjaan dengan Docker

Dalam dua dekade sejak itu, segalanya telah banyak berubah. Situs web menjadi lebih kompleks; mereka harus dirakit sebelum diluncurkan ke produksi. Satu server menjadi banyak server yang berjalan di belakang penyeimbang beban, dan penggunaan sistem kontrol versi menjadi hal biasa.

Untuk proyek pribadi saya, saya memiliki konfigurasi khusus. Dan saya tahu bahwa saya memerlukan kemampuan untuk menerapkan situs dalam produksi hanya dengan melakukan satu tindakan: menulis kode ke cabang master di GitHub. Selain itu, saya tahu bahwa untuk memastikan pengoperasian aplikasi web kecil saya, saya tidak ingin mengelola cluster Kubernetes yang besar, atau menggunakan teknologi Docker Swarm, atau memelihara armada server dengan pod, agen, dan segala macam lainnya. kompleksitas. Untuk mencapai tujuan membuat pekerjaan semudah mungkin, saya perlu mengenal CI/CD.

Jika Anda memiliki proyek kecil (dalam hal ini, proyek Node.js) dan Anda ingin mengetahui cara mengotomatiskan penerapan proyek ini, sambil memastikan bahwa apa yang disimpan dalam repositori sama persis dengan apa yang berfungsi dalam produksi, maka saya Saya pikir Anda mungkin tertarik dengan artikel ini.

Prasyarat

Pembaca artikel ini diharapkan memiliki pemahaman dasar tentang baris perintah dan penulisan skrip Bash. Selain itu, dia akan membutuhkan akun Travis CI ΠΈ Hub Docker.

Tujuan

Saya tidak akan mengatakan bahwa artikel ini tanpa syarat dapat disebut sebagai β€œtutorial”. Ini lebih merupakan dokumen di mana saya berbicara tentang apa yang telah saya pelajari dan menjelaskan proses yang cocok untuk saya untuk menguji dan menerapkan kode ke produksi, yang dilakukan dalam satu proses otomatis.

Inilah alur kerja saya.

Untuk kode yang diposting ke cabang repositori mana pun kecuali master, tindakan berikut dilakukan:

  • Proyek pembangunan Travis CI dimulai.
  • Semua pengujian unit, integrasi, dan ujung ke ujung dilakukan.

Hanya untuk kode yang masuk ke dalamnya master, hal berikut dilakukan:

  • Semua yang disebutkan di atas, ditambah...
  • Membangun image Docker berdasarkan kode, pengaturan, dan lingkungan saat ini.
  • Menyebarkan gambar ke Docker Hub.
  • Koneksi ke server produksi.
  • Mengunggah gambar dari Docker Hub ke server.
  • Menghentikan penampung saat ini dan memulai penampung baru berdasarkan gambar baru.

Jika Anda sama sekali tidak tahu apa pun tentang Docker, image, dan container, jangan khawatir. Aku akan menceritakan semuanya padamu.

Apa itu CI/CD?

Singkatan CI/CD adalah singkatan dari β€œintegrasi berkelanjutan/penyebaran berkelanjutan.”

▍ Integrasi berkelanjutan

Integrasi berkelanjutan adalah proses di mana pengembang membuat komitmen terhadap repositori kode sumber utama proyek (biasanya cabang master). Pada saat yang sama, kualitas kode dipastikan melalui pengujian otomatis.

▍Penyebaran berkelanjutan

Penerapan berkelanjutan adalah penerapan kode secara otomatis dan sering ke dalam produksi. Bagian kedua dari akronim CI/CD kadang-kadang disebut sebagai β€œpengiriman berkelanjutan.” Ini pada dasarnya sama dengan β€œpenyebaran berkelanjutan”, tetapi β€œpengiriman berkelanjutan” menyiratkan kebutuhan untuk mengonfirmasi perubahan secara manual sebelum memulai proses penerapan proyek.

Memulai

Aplikasi yang saya gunakan untuk mempelajari semua ini disebut Perhatikan. Ini adalah proyek web yang sedang saya kerjakan, dirancang untuk membuat catatan. Awalnya saya mencoba melakukannya JAMstack-proyek, atau hanya aplikasi front-end tanpa server, untuk memanfaatkan hosting standar dan kemampuan penerapan proyek yang ditawarkannya netlify. Seiring bertambahnya kompleksitas aplikasi, saya perlu membuat bagian servernya, yang berarti saya perlu merumuskan strategi saya sendiri untuk integrasi otomatis dan penerapan proyek secara otomatis.

Dalam kasus saya, aplikasi tersebut adalah server Express yang berjalan di lingkungan Node.js, melayani aplikasi React satu halaman dan mendukung API sisi server yang aman. Arsitektur ini mengikuti strategi yang dapat ditemukan di ini Panduan otentikasi tumpukan lengkap.

saya berkonsultasi dengan teman, yang merupakan pakar otomasi, dan bertanya kepadanya apa yang perlu saya lakukan agar semuanya berjalan sesuai keinginan saya. Dia memberi saya gambaran tentang seperti apa alur kerja otomatis, yang diuraikan di bagian Sasaran artikel ini. Memiliki tujuan ini berarti saya perlu memikirkan cara menggunakan Docker.

Buruh pelabuhan

Docker adalah alat yang, berkat teknologi containerisasi, memungkinkan aplikasi didistribusikan, diterapkan, dan dijalankan dengan mudah di lingkungan yang sama, meskipun platform Docker itu sendiri berjalan di lingkungan yang berbeda. Pertama, saya perlu mendapatkan alat baris perintah (CLI) Docker. petunjuk Panduan instalasi Docker tidak bisa disebut sangat jelas dan mudah dipahami, tetapi dari situ Anda dapat mengetahui bahwa untuk mengambil langkah instalasi pertama, Anda perlu mengunduh Docker Desktop (untuk Mac atau Windows).

Docker Hub kira-kira sama dengan GitHub untuk repositori git, atau registri npm untuk paket JavaScript. Ini adalah repositori online untuk image Docker. Inilah yang terhubung dengan Docker Desktop.

Jadi, untuk memulai Docker, Anda perlu melakukan dua hal:

Setelah ini, Anda dapat memeriksa apakah Docker CLI berfungsi dengan menjalankan perintah berikut untuk memeriksa versi Docker:

docker -v

Selanjutnya, masuk ke Docker Hub dengan memasukkan nama pengguna dan kata sandi Anda ketika ditanya:

docker login

Untuk menggunakan Docker, Anda harus memahami konsep image dan container.

▍Gambar

Gambar adalah sesuatu seperti cetak biru yang berisi instruksi untuk merakit wadah. Ini adalah cuplikan sistem file dan pengaturan aplikasi yang tidak dapat diubah. Pengembang dapat dengan mudah berbagi gambar.

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

Perintah ini akan menampilkan tabel dengan header berikut:

REPOSITORY     TAG     IMAGE ID     CREATED     SIZE
---

Selanjutnya kita akan melihat beberapa contoh perintah dalam format yang sama - pertama ada perintah dengan komentar, dan kemudian contoh keluarannya.

▍ Wadah

Kontainer adalah paket yang dapat dieksekusi yang berisi semua yang diperlukan untuk menjalankan aplikasi. Aplikasi dengan pendekatan ini akan selalu bekerja dengan cara yang sama, apa pun infrastrukturnya: di lingkungan yang terisolasi dan di lingkungan yang sama. Intinya adalah contoh gambar yang sama diluncurkan di lingkungan yang berbeda.

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

▍Tag

Tag adalah indikasi versi tertentu dari suatu gambar.

▍Referensi cepat ke perintah Docker

Berikut ikhtisar beberapa perintah Docker yang umum digunakan.

Tim

Konteks

efek

membangun buruh pelabuhan

Gambar

Membangun image dari Dockerfile

tanda buruh pelabuhan

Gambar

Penandaan gambar

gambar buruh pelabuhan

Gambar

Daftar gambar

buruh pelabuhan

Wadah

Menjalankan wadah berdasarkan gambar

dorongan buruh pelabuhan

Gambar

Mengunggah gambar ke registri

tarik buruh pelabuhan

Gambar

Memuat gambar dari registri

buruh pelabuhan ps

Wadah

Daftar kontainer

pemangkasan sistem buruh pelabuhan

Gambar/Wadah

Menghapus wadah dan gambar yang tidak digunakan

▍ File Docker

Saya tahu cara menjalankan aplikasi produksi secara lokal. Saya memiliki konfigurasi Webpack yang dirancang untuk membangun aplikasi React yang sudah jadi. Selanjutnya, saya memiliki perintah yang memulai server berbasis Node.js di port 5000. Ini terlihat seperti ini:

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

Perlu dicatat bahwa saya tidak memiliki contoh aplikasi untuk materi ini. Namun di sini, untuk eksperimen, aplikasi Node sederhana apa pun bisa digunakan.

Untuk menggunakan container ini, Anda perlu memberikan instruksi kepada Docker. Ini dilakukan melalui file bernama Dockerfile, terletak di direktori root proyek. File ini, pada awalnya, tampaknya tidak dapat dipahami.

Namun isinya hanya menjelaskan, dengan perintah khusus, sesuatu yang mirip dengan pengaturan lingkungan kerja. Berikut beberapa perintah tersebut:

  • DARI β€” Perintah ini memulai file. Ini menentukan gambar dasar tempat wadah dibuat.
  • COPY β€” Menyalin file dari sumber lokal ke wadah.
  • DIRI KERJA β€” Mengatur direktori kerja untuk perintah berikut.
  • MENJALANKAN - Jalankan perintah.
  • MEMBUKA β€” Pengaturan pelabuhan.
  • TITIK MASUK β€” Indikasi perintah yang akan dieksekusi.

Dockerfile mungkin terlihat 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

Tergantung pada gambar dasar yang Anda pilih, Anda mungkin perlu menginstal dependensi tambahan. Faktanya adalah beberapa image dasar (seperti Node Alpine Linux) dibuat dengan tujuan membuatnya sekompak mungkin. Akibatnya, mereka mungkin tidak mendapatkan beberapa program yang Anda harapkan.

▍Membangun, menandai, dan menjalankan container

Perakitan lokal dan peluncuran kontainer dilakukan setelah kami melakukannya Dockerfile, tugasnya cukup sederhana. Sebelum Anda memasukkan image ke Docker Hub, Anda perlu mengujinya secara lokal.

▍Perakitan

Pertama, Anda perlu mengumpulkan sebuah gambar, menentukan nama dan, opsional, tag (jika tag tidak ditentukan, sistem akan secara otomatis menetapkan tag ke gambar latest).

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

Setelah menjalankan perintah ini, Anda dapat melihat Docker membuat image.

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

Pembuatannya mungkin memakan waktu beberapa menit - semuanya tergantung pada berapa banyak dependensi yang Anda miliki. Setelah build selesai, Anda dapat menjalankan perintah docker images dan lihat deskripsi gambar baru Anda.

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

▍ Peluncuran

Gambar telah dibuat. Ini berarti Anda dapat menjalankan container berdasarkan container tersebut. Karena saya ingin dapat mengakses aplikasi yang berjalan di container di localhost:5000, saya, di sisi kiri pasangan 5000:5000 di perintah berikutnya diinstal 5000. Di sisi kanan adalah pelabuhan kontainer.

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

Sekarang kontainer telah dibuat dan dijalankan, Anda dapat menggunakan perintah docker ps untuk melihat informasi tentang penampung ini (atau Anda dapat menggunakan perintah docker ps -a, yang menampilkan informasi tentang semua container, bukan hanya container yang sedang berjalan).

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 sekarang Anda pergi ke alamatnya localhost:5000 β€” Anda dapat melihat halaman aplikasi yang berjalan yang terlihat sama persis dengan halaman aplikasi yang berjalan di lingkungan produksi.

▍ Pemberian tag dan penerbitan

Untuk menggunakan salah satu image yang dibuat di server produksi, kita harus dapat mendownload image ini dari Docker Hub. Ini berarti Anda harus terlebih dahulu membuat repositori untuk proyek tersebut di Docker Hub. Setelah ini, kita akan memiliki tempat di mana kita dapat mengirim gambar tersebut. Gambar perlu diganti namanya agar namanya dimulai dengan nama pengguna Docker Hub kami. Ini harus diikuti dengan nama repositori. Tag apa pun dapat ditempatkan di akhir nama. Di bawah ini adalah contoh penamaan gambar menggunakan skema ini.

Sekarang Anda dapat membuat gambar dengan nama baru dan menjalankan perintah docker push untuk mendorongnya 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 dengan baik, gambar akan tersedia di Docker Hub dan dapat dengan mudah diunggah ke server atau ditransfer ke pengembang lain.

Langkah selanjutnya

Saat ini kami telah memverifikasi bahwa aplikasi dalam bentuk container Docker berjalan secara lokal. Kami telah mengunggah container ke Docker Hub. Semua ini berarti bahwa kami telah membuat kemajuan yang sangat baik menuju tujuan kami. Sekarang kita perlu menyelesaikan dua pertanyaan lagi:

  • Menyiapkan alat CI untuk menguji dan menerapkan kode.
  • Menyiapkan server produksi agar dapat mengunduh dan menjalankan kode kita.

Dalam kasus kami, kami menggunakan Travis CI. Sebagai server - DigitalOcean.

Perlu dicatat bahwa di sini Anda dapat menggunakan kombinasi layanan lain. Misalnya, alih-alih Travis CI, Anda dapat menggunakan CircleCI atau Github Actions. Dan bukannya DigitalOcean - AWS atau Linode.

Kami memutuskan untuk bekerja dengan Travis CI, dan saya sudah memiliki sesuatu yang dikonfigurasi dalam layanan ini. Oleh karena itu, sekarang saya akan membahas secara singkat bagaimana mempersiapkannya untuk bekerja.

Travis CI

Travis CI adalah alat untuk menguji dan menerapkan kode. Saya tidak ingin membahas seluk-beluk pengaturan Travis CI, karena setiap proyek itu unik, dan ini tidak akan membawa banyak manfaat. Namun saya akan membahas dasar-dasarnya untuk membantu Anda memulai jika Anda memutuskan untuk menggunakan Travis CI. Baik Anda memilih Travis CI, CircleCI, Jenkins, atau yang lainnya, metode konfigurasi serupa akan digunakan di mana saja.

Untuk memulai dengan Travis CI, kunjungi situs web proyek dan membuat akun. Kemudian integrasikan Travis CI dengan akun GitHub Anda. Saat menyiapkan sistem, Anda perlu menentukan repositori yang ingin Anda gunakan untuk mengotomatisasi pekerjaan dan mengaktifkan akses ke sana. (Saya menggunakan GitHub, tapi saya yakin Travis CI dapat berintegrasi dengan BitBucket, GitLab, dan layanan serupa lainnya).

Setiap kali Travis CI dimulai, server diluncurkan, menjalankan perintah yang ditentukan dalam file konfigurasi, termasuk menyebarkan cabang repositori terkait.

▍ Siklus hidup pekerjaan

File konfigurasi Travis CI dipanggil .travis.yml dan disimpan di direktori root proyek, mendukung konsep acara lingkaran kehidupan tugas. Peristiwa-peristiwa ini diurutkan berdasarkan urutan terjadinya:

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

▍Pengujian

Dalam file konfigurasi saya akan mengkonfigurasi server Travis CI lokal. Saya memilih Node 12 sebagai bahasa dan memerintahkan sistem untuk menginstal dependensi yang diperlukan untuk menggunakan Docker.

Segala sesuatu yang tercantum di .travis.yml, akan dieksekusi ketika semua permintaan penarikan dibuat ke semua cabang repositori, kecuali ditentukan lain. Ini adalah fitur yang berguna karena ini berarti kita dapat menguji semua kode yang masuk ke dalam repositori. Ini memberi tahu Anda apakah kode siap untuk ditulis ke cabang. master, dan apakah hal ini akan mengganggu proses pembangunan proyek. Dalam konfigurasi global ini, saya menginstal semuanya secara lokal, menjalankan server dev Webpack di latar belakang (ini adalah fitur alur kerja saya), dan menjalankan pengujian.

Jika Anda ingin repositori Anda menampilkan lencana yang menunjukkan cakupan pengujian, di sini Anda dapat menemukan petunjuk singkat tentang penggunaan Jest, Travis CI, dan Coveralls untuk mengumpulkan dan menampilkan informasi ini.

Jadi inilah isi filenya .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 cabang repositori dan permintaan tarik berakhir.

▍Penempatan

Berdasarkan asumsi bahwa semua pengujian otomatis berhasil diselesaikan, kami dapat, yang bersifat opsional, menyebarkan kode ke server produksi. Karena kami ingin melakukan ini hanya untuk kode dari cabang master, kami memberikan instruksi yang sesuai kepada sistem dalam pengaturan penerapan. Sebelum Anda mencoba menggunakan kode yang akan kita lihat selanjutnya dalam proyek Anda, saya ingin memperingatkan Anda bahwa Anda harus memiliki skrip sebenarnya yang diperlukan untuk penerapan.

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

Skrip penerapan memecahkan dua masalah:

  • Buat, tandai, dan kirim gambar ke Docker Hub menggunakan alat CI (dalam kasus kami, Travis CI).
  • Memuat gambar di server, menghentikan penampung lama dan memulai yang baru (dalam kasus kami, server berjalan pada platform DigitalOcean).

Pertama, Anda perlu menyiapkan proses otomatis untuk membuat, menandai, dan memasukkan image ke Docker Hub. Ini semua sangat mirip dengan apa yang telah kita lakukan secara manual, hanya saja kita memerlukan strategi untuk menetapkan tag unik pada gambar dan mengotomatiskan login. Saya mengalami kesulitan dengan beberapa detail skrip penerapan, seperti strategi penandaan, login, pengkodean kunci SSH, pembuatan koneksi SSH. Tapi untungnya pacarku sangat pandai dalam pesta, seperti banyak hal lainnya. Dia membantuku menulis naskah ini.

Jadi, bagian pertama dari skrip adalah mengunggah gambar ke Docker Hub. Hal ini cukup mudah dilakukan. Skema penandaan yang saya gunakan melibatkan penggabungan git hash dan git tag, jika ada. Hal ini memastikan bahwa tag tersebut unik dan memudahkan untuk mengidentifikasi rakitan yang menjadi dasarnya. DOCKER_USERNAME ΠΈ DOCKER_PASSWORD adalah variabel lingkungan pengguna yang dapat diatur menggunakan antarmuka Travis CI. Travis CI akan secara otomatis memproses data sensitif agar tidak jatuh ke tangan yang salah.

Ini adalah bagian pertama dari naskahnya 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}

Bagian kedua dari skrip ini bergantung sepenuhnya pada host yang Anda gunakan dan bagaimana koneksi ke host tersebut diatur. Dalam kasus saya, karena saya menggunakan Digital Ocean, saya menggunakan perintah untuk terhubung ke server doktl. Saat bekerja dengan AWS, utilitas akan digunakan aws, dan seterusnya.

Menyiapkan server tidak terlalu sulit. Jadi, saya menyiapkan tetesan berdasarkan gambar dasar. Perlu dicatat bahwa sistem yang saya pilih memerlukan instalasi Docker manual satu kali dan peluncuran Docker manual satu kali. Saya menggunakan Ubuntu 18.04 untuk menginstal Docker, jadi jika Anda juga menggunakan Ubuntu untuk melakukan hal yang sama, Anda cukup mengikuti ini panduan sederhana.

Saya tidak berbicara di sini tentang perintah khusus untuk layanan ini, karena aspek ini dapat sangat bervariasi dalam berbagai kasus. Saya hanya akan memberikan rencana umum tindakan yang perlu dilakukan setelah terhubung melalui SSH ke server tempat proyek akan diterapkan:

  • Kita perlu menemukan container yang sedang berjalan dan menghentikannya.
  • Maka Anda perlu meluncurkan wadah baru di latar belakang.
  • Anda perlu menyetel port lokal server ke 80 - ini akan memungkinkan Anda memasuki situs di alamat seperti example.com, tanpa menentukan port, daripada menggunakan alamat seperti example.com:5000.
  • Terakhir, Anda perlu menghapus semua container dan gambar lama.

Berikut kelanjutan skripnya.

# Найти 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 hal yang perlu diperhatikan

Ada kemungkinan ketika Anda terhubung ke server melalui SSH dari Travis CI, Anda akan melihat peringatan yang menghalangi Anda untuk melanjutkan instalasi karena 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 bahwa kunci string dapat dikodekan dalam base64 untuk menyimpannya dalam bentuk yang dapat digunakan dengan mudah dan andal. Pada tahap instalasi, Anda dapat mendekode kunci publik dan menuliskannya ke file known_hosts untuk menghilangkan kesalahan di atas.

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

Dalam praktiknya, perintah ini mungkin terlihat 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 - string yang dikodekan base64:

MTIzLjQ1LjY3Ljg5IHNzaC1yc2EgQUFBQUIzTnphQzF5YzJFQUFBQUJJd0FBQVFFQWtsT1Vwa0RIcmZIWTE3U2JybVRJcE5MVEdLOVRqb20vQldEU1UKR1BsK25hZnpsSERUWVc3aGRJNHlaNWV3MThKSDRKVzlqYmhVRnJ2aVF6TTd4bEVMRVZmNGg5bEZYNVFWa2JQcHBTd2cwY2RhMwpQYnY3a09kSi9NVHlCbFdYRkNSK0hBbzNGWFJpdEJxeGlYMW5LaFhwSEFac01jaUxxOFY2UmpzTkFRd2RzZE1GdlNsVksvN1hBCnQzRmFvSm9Bc25jTTFROXg1KzNWMFd3NjgvZUlGbWIxenVVRmxqUUpLcHJyWDg4WHlwTkR2allOYnk2dncvUGIwcndlcnQvRW4KbVorQVc0T1pQblRQSTg5WlBtVk1MdWF5ckQyY0U4NlovaWw4YitndzNyMysxbkthdG1Ja2puMnNvMWQwMVFyYVRsTXFWU3NieApOclJGaTl3cmYrTTdRPT0geW91QGV4YW1wbGUuY29tCg==

Berikut adalah perintah yang disebutkan di atas

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

Pendekatan yang sama dapat digunakan dengan kunci pribadi saat membuat koneksi, karena Anda mungkin memerlukan kunci pribadi untuk mengakses server. Saat bekerja dengan kunci, Anda hanya perlu memastikan bahwa kunci tersebut disimpan dengan aman di variabel lingkungan Travis CI dan tidak ditampilkan di mana pun.

Hal lain yang perlu diperhatikan adalah Anda mungkin perlu menjalankan seluruh skrip penerapan sebagai satu baris, misalnya - dengan doctl. Ini mungkin memerlukan usaha ekstra.

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

TLS/SSL dan Penyeimbangan Beban

Setelah saya melakukan semua hal di atas, masalah terakhir yang saya temui adalah server tidak memiliki SSL. Karena saya menggunakan server Node.js, untuk memaksa untuk bekerja membalikkan proxy Nginx dan Let's Encrypt, Anda perlu banyak mengutak-atik.

Saya sebenarnya tidak ingin melakukan semua konfigurasi SSL ini secara manual, jadi saya hanya membuat load balancer dan mencatat detailnya di DNS. Dalam kasus DigitalOcean, misalnya, membuat sertifikat yang ditandatangani sendiri dan diperpanjang secara otomatis pada penyeimbang beban adalah prosedur yang sederhana, gratis, dan cepat. Pendekatan ini memiliki manfaat tambahan yaitu membuatnya sangat mudah untuk menyiapkan SSL di beberapa server yang berjalan di belakang penyeimbang beban jika diperlukan. Hal ini memungkinkan server itu sendiri untuk tidak β€œberpikir” tentang SSL sama sekali, tetapi pada saat yang sama menggunakan port tersebut seperti biasa 80. Jadi menyiapkan SSL pada penyeimbang beban jauh lebih mudah dan nyaman dibandingkan metode alternatif untuk menyiapkan SSL.

Sekarang Anda dapat menutup semua port di server yang menerima koneksi masuk - kecuali port tersebut 80, digunakan untuk berkomunikasi dengan penyeimbang beban, dan port 22 untuk SSH. Akibatnya, upaya untuk mengakses server secara langsung pada port mana pun selain kedua port ini akan gagal.

Hasil

Setelah saya melakukan semua yang saya bicarakan dalam materi ini, baik platform Docker maupun konsep rantai CI/CD otomatis tidak lagi membuat saya takut. Saya dapat menyiapkan rantai integrasi berkelanjutan, di mana kode diuji sebelum masuk ke produksi dan kode tersebut secara otomatis diterapkan di server. Ini semua masih relatif baru bagi saya, dan saya yakin ada cara untuk meningkatkan alur kerja otomatis saya dan membuatnya lebih efisien. Jadi, jika Anda punya ide tentang masalah ini, beri tahu saya. ΠΌΠ½Π΅ tahu. Saya harap artikel ini membantu usaha Anda. Saya ingin percaya bahwa setelah membacanya, Anda belajar sebanyak yang saya pelajari sambil memahami semua yang saya bicarakan di dalamnya.

PS Di kami pasar ada gambar Buruh pelabuhan, yang dapat diinstal dalam satu klik. Anda dapat memeriksa pengoperasian kontainer di VPS. Semua klien baru diberikan 3 hari pengujian gratis.

Pembaca yang terhormat Apakah Anda menggunakan teknologi CI/CD dalam proyek Anda?

Membuat rantai CI/CD dan mengotomatiskan pekerjaan dengan Docker

Sumber: www.habr.com

Tambah komentar