CI/CD di Github Actions untuk proyek Flask+Angular

CI/CD di Github Actions untuk proyek Flask+Angular
Pada artikel ini, saya akan membagikan pengalaman saya mengatur CI/CD menggunakan Plesk Control Panel dan Github Actions. Hari ini kita akan belajar cara menerapkan proyek sederhana dengan nama sederhana "Helloworld". Itu ditulis dalam kerangka kerja Flask Python, dengan pekerja Seledri dan frontend Angular 8.

Tautan ke repositori: backend, paling depan.

Di bagian pertama artikel, kita akan melihat proyek kita dan bagian-bagiannya. Yang kedua, kita akan mengetahui cara mengatur Plesk dan menginstal ekstensi dan komponen yang diperlukan (DB, RabbitMQ, Redis, Docker, dll.).

Di bagian ketiga, kita akhirnya akan mengetahui cara menyiapkan pipeline untuk menerapkan proyek kita ke server di lingkungan dev dan prod. Dan kemudian kami akan meluncurkan situs di server.

Dan ya, aku lupa memperkenalkan diri. Nama saya Oleg Borzov, saya adalah pengembang fullstack di tim CRM untuk manajer hipotek di Domclick.

Ikhtisar proyek

Pertama, mari kita lihat dua repositori proyek - backend dan front - dan lihat kodenya.

Bagian belakang: Labu + Seledri

Untuk bagian belakang, saya mengambil beberapa yang cukup populer di kalangan developer Python: framework Flask (untuk API) dan Celery (untuk antrian tugas). SQLAchemy digunakan sebagai ORM. Alembic digunakan untuk migrasi. Untuk validasi JSON di pegangan - Marshmallow.

Π’ repositori ada file Readme.md dengan deskripsi mendetail tentang struktur dan instruksi untuk menjalankan proyek.

API Bagian Web cukup sederhana, terdiri dari 6 pulpen:

  • /ping - untuk memeriksa ketersediaan;
  • pegangan untuk pendaftaran, otorisasi, de-otorisasi dan mendapatkan pengguna yang berwenang;
  • pegangan email yang menempatkan tugas dalam antrian Seledri.

Bagian seledri lebih mudah lagi, hanya ada satu masalah send_mail_task.

Dalam folder / conf ada dua subfolder:

  • docker dengan dua Dockerfiles (base.dockerfile untuk membangun gambar dasar yang jarang berubah dan Dockerfile untuk rakitan utama);
  • .env_files - dengan file dengan variabel lingkungan untuk lingkungan yang berbeda.

Ada empat file pembuat buruh pelabuhan di akar proyek:

  • docker-compose.local.db.yml untuk meningkatkan database lokal untuk pembangunan;
  • docker-compose.local.workers.yml untuk pemeliharaan lokal pekerja, basis data, Redis dan RabbitMQ;
  • docker-compose.test.yml untuk menjalankan tes selama penerapan;
  • docker-compose.yml untuk penerapan.

Dan folder terakhir yang kami minati - .ci-cd. Ini berisi skrip shell untuk penerapan:

  • deploy.sh β€” peluncuran migrasi dan penerapan. Berjalan di server setelah membuat dan menjalankan pengujian di Github Actions;
  • rollback.sh - kembalikan kontainer ke versi perakitan sebelumnya;
  • curl_tg.sh - mengirim pemberitahuan penerapan ke Telegram.

Frontend di Angular

Repositori dengan depan jauh lebih sederhana daripada Beck. Bagian depan terdiri dari tiga halaman:

  • Halaman utama dengan formulir untuk mengirim email dan tombol keluar.
  • Halaman masuk.
  • halaman pendaftaran.

Halaman utama terlihat pertapa:

CI/CD di Github Actions untuk proyek Flask+Angular
Ada dua file di root Dockerfile ΠΈ docker-compose.yml, serta folder yang sudah dikenal .ci-cd dengan skrip yang sedikit lebih sedikit daripada di repositori belakang (skrip yang dihapus untuk menjalankan pengujian).

Memulai proyek di Plesk

Mari kita mulai dengan menyiapkan Plesk dan membuat langganan untuk situs kita.

Memasang ekstensi

Di Plesk, kami membutuhkan empat ekstensi:

  • Docker untuk mengelola dan menampilkan status wadah secara visual di panel admin Plesk;
  • Git untuk mengonfigurasi langkah penerapan di server;
  • Let's Encrypt untuk menghasilkan (dan memperbarui otomatis) sertifikat TLS gratis;
  • Firewall untuk mengonfigurasi pemfilteran lalu lintas masuk.

Anda dapat menginstalnya melalui panel admin Plesk di bagian Ekstensi:

CI/CD di Github Actions untuk proyek Flask+Angular
Kami tidak akan mempertimbangkan pengaturan terperinci untuk ekstensi, pengaturan default akan dilakukan untuk tujuan demo kami.

Buat langganan dan situs

Selanjutnya, kita perlu membuat langganan untuk situs web helloworld.ru kita dan menambahkan subdomain dev.helloworld.ru di sana.

  1. Buat langganan untuk domain helloworld.ru dan tentukan kata sandi masuk untuk pengguna sistem:

    CI/CD di Github Actions untuk proyek Flask+Angular
    Centang kotak di bagian bawah halaman Amankan domain dengan Let's Encryptjika kami ingin menyiapkan HTTPS untuk situs:

    CI/CD di Github Actions untuk proyek Flask+Angular

  2. Selanjutnya, dalam langganan ini, buat subdomain dev.helloworld.ru (di mana Anda juga dapat mengeluarkan sertifikat TLS gratis):

    CI/CD di Github Actions untuk proyek Flask+Angular

Menginstal Komponen Server

Kami memiliki server dengan OS Debian Peregangan 9.12 dan memasang panel kontrol Plesk Obsidian 18.0.27.

Kita perlu menginstal dan mengonfigurasi untuk proyek kita:

  • PostgreSQL (dalam kasus kami, akan ada satu server dengan dua database untuk lingkungan dev dan prod).
  • RabbitMQ (sama, instance yang sama dengan vhost berbeda untuk lingkungan).
  • Dua instance Redis (untuk lingkungan dev dan prod).
  • Docker Registry (untuk penyimpanan lokal gambar Docker bawaan).
  • UI untuk registri Docker.

PostgreSQL

Plesk sudah hadir dengan DBMS PostgreSQL, tetapi bukan versi terbaru (pada saat penulisan Plesk Obsidian didukung Postgres versi 8.4–10.8). Kami menginginkan versi terbaru untuk aplikasi kami (12.3 pada saat penulisan ini), jadi kami akan menginstalnya secara manual.

Ada banyak instruksi mendetail untuk menginstal Postgres di Debian di internet (contoh), jadi saya tidak akan menjelaskannya secara detail, saya hanya akan memberikan perintah:

wget -q https://www.postgresql.org/media/keys/ACCC4CF8.asc -O - | sudo apt-key add -
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt/ stretch-pgdg main" >> /etc/apt/sources.list.d/pgdg.list'

sudo apt-get update
sudo apt-get install postgresql postgresql-contrib

Mengingat PostgreSQL memiliki pengaturan default yang agak biasa-biasa saja, konfigurasi perlu diperbaiki. Ini akan membantu kita kalkulator: Anda perlu memasukkan parameter server Anda dan mengganti pengaturan di file /etc/postgresql/12/main/postgresql.confkepada yang ditawarkan. Perlu dicatat di sini bahwa kalkulator semacam itu bukanlah peluru ajaib, dan basisnya harus disetel lebih tepat, berdasarkan kompleksitas perangkat keras, aplikasi, dan kueri Anda. Tapi ini cukup untuk memulai.

Selain pengaturan yang diusulkan oleh kalkulator, kami juga mengubahnya postgresql.confport default 5432 ke yang lain (dalam contoh kami - 53983).

Setelah mengubah file konfigurasi, restart postgresql-server dengan perintah:

service postgresql restart

Kami telah menginstal dan mengkonfigurasi PostgreSQL. Sekarang mari buat database, pengguna untuk lingkungan dev dan prod, dan berikan hak pengguna untuk mengelola database:

$ su - postgres
postgres:~$ create database hw_dev_db_name;
CREATE DATABASE
postgres:~$ create user hw_dev_db_user with password 'hw_dev_db_password';
CREATE ROLE
postgres:~$ grant ALL privileges ON database hw_dev_db_name to hw_dev_db_user;
GRANT
postgres:~$ create database hw_prod_db_name;
CREATE DATABASE
postgres:~$ create user hw_prod_db_user with password 'hw_prod_db_password';
CREATE ROLE
postgres:~$ grant ALL privileges ON database hw_prod_db_name to hw_prod_db_user;
GRANT

RabbitMQ

Mari lanjutkan dengan menginstal RabbitMQ, broker pesan untuk Celery. Menginstalnya di Debian cukup sederhana:

wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb
sudo dpkg -i erlang-solutions_1.0_all.deb

sudo apt-get update
sudo apt-get install erlang erlang-nox

sudo add-apt-repository 'deb http://www.rabbitmq.com/debian/ testing main'
wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -

sudo apt-get update
sudo apt-get install rabbitmq-server

Setelah instalasi, kita perlu membuat vhosts, pengguna dan memberikan hak yang diperlukan:

sudo rabbitmqctl add_user hw_dev_amqp_user hw_dev_amqp_password 
sudo rabbitmqctl set_user_tags hw_dev_amqp_user administrator
sudo rabbitmqctl add_vhost hw_dev_vhost
sudo rabbitmqctl set_permissions -p hw_dev_vhost hw_dev_amqp_user ".*" ".*" ".*"

sudo rabbitmqctl add_user hw_prod_amqp_user hw_prod_amqp_password 
sudo rabbitmqctl set_user_tags hw_prod_amqp_user administrator
sudo rabbitmqctl add_vhost hw_prod_vhost
sudo rabbitmqctl set_permissions -p hw_prod_vhost hw_prod_amqp_user ".*" ".*" ".*"

Redis

Sekarang mari instal dan konfigurasikan komponen terakhir untuk aplikasi kita - Redis. Ini akan digunakan sebagai backend untuk menyimpan hasil tugas Celery.

Kami akan meningkatkan dua kontainer Docker dengan Redis untuk lingkungan dev dan prod menggunakan ekstensi Docker untuk Plesk.

  1. Kami pergi ke Plesk, pergi ke bagian Ekstensi, cari ekstensi Docker dan instal (kami memerlukan versi gratis):

    CI/CD di Github Actions untuk proyek Flask+Angular

  2. Buka ekstensi yang diinstal, temukan gambar melalui pencarian redis bitnami dan instal versi terbaru:

    CI/CD di Github Actions untuk proyek Flask+Angular

  3. Kami masuk ke wadah yang diunduh dan menyesuaikan konfigurasi: tentukan port, ukuran RAM yang dialokasikan maksimum, kata sandi dalam variabel lingkungan, dan pasang volume:

    CI/CD di Github Actions untuk proyek Flask+Angular

  4. Kami melakukan langkah 2-3 untuk wadah prod, dalam pengaturan kami hanya mengubah parameter: port, kata sandi, ukuran RAM, dan jalur ke folder volume di server:

    CI/CD di Github Actions untuk proyek Flask+Angular

Registri Docker

Selain layanan dasar, alangkah baiknya untuk menempatkan repositori gambar Docker Anda sendiri di server. Untungnya, ruang server sekarang cukup murah (tentunya lebih murah daripada langganan DockerHub), dan proses menyiapkan repositori pribadi sangat sederhana.

Kami ingin memiliki:

Untuk melakukan hal ini:

  1. Mari buat dua subdomain di Plesk di langganan kami: docker.helloworld.ru dan docker-ui.helloworld.ru, dan konfigurasikan sertifikat Let's Encrypt untuk mereka.
  2. Tambahkan file ke folder subdomain docker.helloworld.ru docker-compose.yml dengan konten seperti ini:
    version: "3"
    
    services:
      docker-registry:
        image: "registry:2"
        restart: always
        ports:
          - "53985:5000"
        environment:
          REGISTRY_AUTH: htpasswd
          REGISTRY_AUTH_HTPASSWD_REALM: basic-realm
          REGISTRY_AUTH_HTPASSWD_PATH: /auth/.htpasswd
          REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: /data
        volumes:
          - ./.docker-registry.htpasswd:/auth/.htpasswd
          - ./data:/data
    
      docker-registry-ui:
        image: konradkleine/docker-registry-frontend:v2
        restart: always
        ports:
          - "53986:80"
        environment:
          VIRTUAL_HOST: '*, https://*'
          ENV_DOCKER_REGISTRY_HOST: 'docker-registry'
          ENV_DOCKER_REGISTRY_PORT: 5000
        links:
          - 'docker-registry'
    

  3. Di bawah SSH, kami akan membuat file .htpasswd untuk otorisasi Dasar di repositori Docker:
    htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password
  4. Kumpulkan dan angkat kontainer:
    docker-compose up -d
  5. Dan kita perlu mengarahkan ulang Nginx ke wadah kita. Ini dapat dilakukan melalui Plesk.

Langkah-langkah berikut perlu dilakukan untuk subdomain docker.helloworld.ru dan docker-ui.helloworld.ru:

Pada bagian Alat Pengembangan situs kami pergi ke Aturan Proksi Docker:

CI/CD di Github Actions untuk proyek Flask+Angular
Dan tambahkan aturan untuk mem-proksi lalu lintas masuk ke penampung kami:

CI/CD di Github Actions untuk proyek Flask+Angular

  1. Kami memeriksa apakah kami dapat masuk ke wadah kami dari mesin lokal:
    $ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password
    WARNING! Using --password via the CLI is insecure. Use --password-stdin.
    Login Succeeded
  2. Mari kita periksa juga pengoperasian subdomain docker-ui.helloworld.ru:

    CI/CD di Github Actions untuk proyek Flask+Angular
    Ketika Anda mengklik Telusuri repositori, browser akan menampilkan jendela otorisasi di mana Anda harus memasukkan nama pengguna dan kata sandi untuk repositori. Setelah itu, kami akan dipindahkan ke halaman dengan daftar repositori (untuk saat ini, akan kosong untuk Anda):

    CI/CD di Github Actions untuk proyek Flask+Angular

Membuka port di Plesk Firewall

Setelah menginstal dan mengonfigurasi komponen, kita perlu membuka port agar komponen dapat diakses dari wadah Docker dan jaringan eksternal.

Mari kita lihat bagaimana melakukan ini menggunakan ekstensi Firewall untuk Plesk yang telah kita instal sebelumnya.

  1. Pergi ke Alat & Setelan > Setelan > Firewall:
    CI/CD di Github Actions untuk proyek Flask+Angular
  2. Pergi ke Ubah Aturan Firewall Plesk > Tambahkan Aturan Kustom dan buka port TCP berikut untuk subnet Docker (172.0.0.0 / 8):
    KelinciMQ: 1883, 4369, 5671-5672, 25672, 61613-61614
    Redis: 32785, 32786

    CI/CD di Github Actions untuk proyek Flask+Angular

  3. Kami juga akan menambahkan aturan yang akan membuka port PostgreSQL dan panel manajemen RabbitMQ ke dunia luar:

    CI/CD di Github Actions untuk proyek Flask+Angular

  4. Terapkan aturan menggunakan tombol Terapkan Perubahan:

    CI/CD di Github Actions untuk proyek Flask+Angular

Menyiapkan CI/CD di Github Actions

Mari kita ke bagian yang paling menarik - menyiapkan pipa integrasi berkelanjutan dan mengirimkan proyek kita ke server.

Pipa ini akan terdiri dari dua bagian:

  • membangun gambar dan menjalankan tes (untuk backend) - di sisi Github;
  • menjalankan migrasi (untuk backend) dan menggunakan kontainer - di server.

Terapkan ke Plesk

Mari kita bahas poin kedua terlebih dahulu (karena poin pertama bergantung padanya).

Kami akan mengonfigurasi proses penerapan menggunakan ekstensi Git untuk Plesk.

Pertimbangkan contoh dengan lingkungan Prod untuk repositori Backend.

  1. Kami pergi ke langganan situs web Helloworld kami dan pergi ke subbagian Git:

    CI/CD di Github Actions untuk proyek Flask+Angular

  2. Masukkan tautan ke repositori Github kami ke dalam bidang "Repositori Remote Git" dan ubah folder default httpdocs ke yang lain (mis. /httpdocs/hw_back):

    CI/CD di Github Actions untuk proyek Flask+Angular

  3. Salin kunci Publik SSH dari langkah sebelumnya dan Menambahkan ada di pengaturan Github.
  4. Klik OK pada layar pada langkah 2, setelah itu kita akan diarahkan ke halaman repositori di Plesk. Sekarang kita perlu mengonfigurasi repositori untuk diperbarui saat komit ke cabang master. Untuk melakukan ini, buka Pengaturan Repositori dan simpan nilainya Webhook URL (kita akan membutuhkannya nanti saat menyiapkan Github Actions):

    CI/CD di Github Actions untuk proyek Flask+Angular

  5. Di bidang Tindakan di layar dari paragraf sebelumnya, masukkan skrip untuk meluncurkan penerapan:
    cd {REPOSITORY_ABSOLUTE_PATH}
    .ci-cd/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} 

    di mana:

    {REPOSITORY_ABSOLUTE_PATH} - path ke folder prod dari repositori backend di server;
    {ENV} - lingkungan (dev / prod), dalam kasus kami prod;
    {DOCKER_REGISTRY_HOST} - tuan rumah repositori buruh pelabuhan kami
    {TG_BOT_TOKEN} β€” Token bot Telegram;
    {TG_CHAT_ID} β€” ID obrolan/saluran untuk mengirim notifikasi.

    Contoh skrip:

    cd /var/www/vhosts/helloworld.ru/httpdocs/hw_back/
    .ci-cd/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890
  6. Tambahkan pengguna dari langganan kami ke grup Docker (sehingga mereka dapat mengelola kontainer):
    sudo usermod -aG docker helloworld_admin

Lingkungan dev untuk repositori backend dan frontend disiapkan dengan cara yang sama.

Pipeline penerapan di Github Actions

Mari beralih ke menyiapkan bagian pertama dari pipeline CI/CD kita di Github Actions.

Backend

Pipa dijelaskan dalam menyebarkan.yml file.

Namun sebelum menguraikannya, mari kita isi variabel Rahasia yang kita butuhkan di Github. Untuk melakukan ini, buka Pengaturan -> Rahasia:

  • DOCKER_REGISTRY - host repositori Docker kami (docker.helloworld.ru);
  • DOCKER_LOGIN - masuk ke repositori Docker;
  • DOCKER_PASSWORD - kata sandi untuk itu;
  • DEPLOY_HOST β€” host tempat panel admin Plesk tersedia (contoh: helloworld.com: 8443 atau 123.4.56.78:8443);
  • DEPLOY_BACK_PROD_TOKEN - token untuk penerapan ke prod-repository di server (kami mendapatkannya di Deployment in Plesk p.4);
  • DEPLOY_BACK_DEV_TOKEN - token untuk ditempatkan ke repositori dev di server.

Proses penerapannya sederhana dan terdiri dari tiga langkah utama:

  • membangun dan menerbitkan gambar di repositori kami;
  • menjalankan tes dalam wadah berdasarkan gambar yang baru dibuat;
  • penyebaran ke lingkungan yang diinginkan tergantung pada cabang (dev/master).

Frontend

File deploy.yml untuk repositori depan sedikit berbeda dari Beck. Itu tidak memiliki langkah dengan menjalankan tes dan mengubah nama token untuk penerapan. Omong-omong, rahasia untuk repositori depan perlu diisi secara terpisah.

Pengaturan situs

Proksi lalu lintas melalui Nginx

Nah, kita telah sampai pada akhirnya. Tinggal mengonfigurasi proksi lalu lintas masuk dan keluar ke wadah kami melalui Nginx. Kami telah membahas proses ini di langkah 5 dari pengaturan Docker Registry. Hal yang sama harus diulangi untuk bagian belakang dan depan di lingkungan dev dan prod.

Saya akan memberikan tangkapan layar pengaturan.

Backend

CI/CD di Github Actions untuk proyek Flask+Angular

Frontend

CI/CD di Github Actions untuk proyek Flask+Angular
Π°ΠΆΠ½ΠΎΠ΅ ΠΎΡ‡Π½Π΅Π½ΠΈΠ΅. Semua URL akan diproksi ke wadah frontend, kecuali yang dimulai dengan /api/ - mereka akan diproksi ke wadah belakang (jadi di wadah belakang, semua penangan harus memulai dengan /api/).

Hasil

Sekarang situs kami harus tersedia di helloworld.ru dan dev.helloworld.ru (prod- dan dev-environments, masing-masing).

Secara total, kami belajar cara menyiapkan aplikasi sederhana di Flask dan Angular dan menyiapkan pipeline di Github Actions untuk meluncurkannya ke server yang menjalankan Plesk.

Saya akan menggandakan tautan ke repositori dengan kode: backend, paling depan.

Sumber: www.habr.com

Tambah komentar