{"id":85646,"date":"2020-06-18T01:42:15","date_gmt":"2020-06-17T23:42:15","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/ci-cd-v-github-actions-dlya-proekta-na-flask-angular"},"modified":"2020-06-18T01:42:15","modified_gmt":"2020-06-17T23:42:15","slug":"ci-cd-v-github-actions-dlya-proekta-na-flask-angular","status":"publish","type":"post","link":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/ci-cd-v-github-actions-dlya-proekta-na-flask-angular","title":{"rendered":"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/26d0945a41bbf3c98fa92f15be5b8c6c.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nEbben a cikkben megosztom tapasztalataimat a CI\/CD be\u00e1ll\u00edt\u00e1s\u00e1r\u00f3l a Plesk vez\u00e9rl\u0151pult \u00e9s a Github Actions seg\u00edts\u00e9g\u00e9vel. Ma egy egyszer\u0171, \"Helloworld\" nev\u0171 projekt telep\u00edt\u00e9s\u00e9t fogjuk megtanulni. Ez a Flask Python keretrendszerben k\u00e9sz\u00fclt, Celery munk\u00e1sokkal \u00e9s Angular 8 front-enddel.<\/p>\n<p><b>A repository-k linkjei:<\/b> <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld_back\">h\u00e1tt\u00e9r<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld-front\">frontend<\/a><\/noindex>.<\/p>\n<p>A cikk els\u0151 r\u00e9sz\u00e9ben megn\u00e9zz\u00fck a projekt\u00fcnket \u00e9s annak r\u00e9szeit. A m\u00e1sodik r\u00e9szben pedig azt t\u00e1rgyaljuk, hogyan \u00e1ll\u00edtsuk be a Plesk-t \u00e9s telep\u00edts\u00fck a sz\u00fcks\u00e9ges kiterjeszt\u00e9seket \u00e9s komponenseket (adatb\u00e1zis, RabbitMQ, Redis, Docker stb.).<\/p>\n<p>A harmadik r\u00e9szben v\u00e9g\u00fcl arra is r\u00e1t\u00e9r\u00fcnk, hogyan \u00e1ll\u00edtsuk be a pipeline-t a projekt\u00fcnk szerverre t\u00f6rt\u00e9n\u0151 telep\u00edt\u00e9s\u00e9hez dev- \u00e9s prod-k\u00f6rnyezetbe. Azt\u00e1n elind\u00edtjuk a weboldalt a szerveren.<\/p>\n<p>\u00c9s igen, elfelejtettem bemutatkozni. Oleg Borzov vagyok, fullstack fejleszt\u0151 a lak\u00e1shitel menedzserek CRM csapat\u00e1ban a Domklikn\u00e9l. <br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<h1>A projekt \u00e1ttekint\u00e9se<\/h1>\n<p>\nEl\u0151sz\u00f6r n\u00e9zz\u00fck meg a projekt k\u00e9t repository-j\u00e1t \u2014 a h\u00e1tt\u00e9r \u00e9s a frontend \u2014 \u00e9s fussunk \u00e1t a k\u00f3don.<\/p>\n<h2>H\u00e1tt\u00e9r r\u00e9sz: Flask+Celery<\/h2>\n<p>\nA h\u00e1tt\u00e9rhez egy a Python fejleszt\u0151k k\u00f6r\u00e9ben el\u00e9g n\u00e9pszer\u0171 \u00f6ssze\u00e1ll\u00edt\u00e1st v\u00e1lasztottam: a Flask keretrendszert (az API-hoz) \u00e9s a Celery-t (a feladatok sorba \u00e1ll\u00edt\u00e1s\u00e1hoz). Az ORM SQLAlchemy-t haszn\u00e1l. Az adatb\u00e1zis-migr\u00e1ci\u00f3khoz Alembic-et alkalmazunk. A JSON valid\u00e1l\u00e1s\u00e1ra a Marshmallow-t.<\/p>\n<p>A <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld_back\">t\u00e1rhelyen<\/a><\/noindex> van egy Readme.md f\u00e1jl r\u00e9szletes le\u00edr\u00e1ssal a strukt\u00far\u00e1r\u00f3l \u00e9s a projekt ind\u00edt\u00e1si utas\u00edt\u00e1sair\u00f3l.<\/p>\n<p><noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld_back\/tree\/master\/app_web\">API web r\u00e9sz<\/a><\/noindex> kifejezetten egyszer\u0171, 6 v\u00e9gpontb\u00f3l \u00e1ll:<\/p>\n<ul>\n<li><code>\/ping<\/code> \u2014 a rendelkez\u00e9sre \u00e1ll\u00e1s ellen\u0151rz\u00e9s\u00e9re;<\/li>\n<li>v\u00e9gpontok a regisztr\u00e1l\u00e1shoz, bejelentkez\u00e9shez, kijelentkez\u00e9shez \u00e9s a bejelentkezett felhaszn\u00e1l\u00f3 lek\u00e9r\u00e9s\u00e9hez;<\/li>\n<li>v\u00e9gpont, amely emailt k\u00fcld, \u00e9s a feladatot a Celery sorba helyezi.<\/li>\n<\/ul>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld_back\/tree\/master\/app_celery\">Celery r\u00e9sz<\/a><\/noindex> m\u00e9g egyszer\u0171bb, itt mind\u00f6ssze egy feladat van <code>send_mail_task<\/code>.<\/p>\n<p>A mapp\u00e1ban <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld_back\/tree\/master\/conf\/\">\/conf<\/a><\/noindex> k\u00e9t alk\u00f6nyvt\u00e1r tal\u00e1lhat\u00f3: <\/p>\n<ul>\n<li><code>docker<\/code> k\u00e9t Docker f\u00e1jllal (<code>base.dockerfile<\/code> ritk\u00e1n v\u00e1ltoz\u00f3 alapk\u00e9pek \u00f6ssze\u00e1ll\u00edt\u00e1s\u00e1hoz \u00e9s <code>Dockerfile<\/code> a f\u0151 \u00f6ssze\u00e1ll\u00edt\u00e1sokhoz);<\/li>\n<li><code>.env_files<\/code> \u2014 k\u00f6rnyezeti v\u00e1ltoz\u00f3kkal ell\u00e1tott f\u00e1jlok a k\u00fcl\u00f6nb\u00f6z\u0151 k\u00f6rnyezetekhez. <\/li>\n<\/ul>\n<p>\nA projekt gy\u00f6ker\u00e9ben n\u00e9gy docker-compose f\u00e1jl tal\u00e1lhat\u00f3:<\/p>\n<ul>\n<li><code>docker-compose.local.db.yml<\/code> a helyi adatb\u00e1zis felemel\u00e9s\u00e9hez fejleszt\u00e9shez;<\/li>\n<li><code>docker-compose.local.workers.yml<\/code> a helyi munk\u00e1s, adatb\u00e1zis, Redis \u00e9s RabbitMQ felemel\u00e9s\u00e9hez;<\/li>\n<li><code>docker-compose.test.yml<\/code> a tesztek futtat\u00e1s\u00e1hoz a telep\u00edt\u00e9s sor\u00e1n;<\/li>\n<li><code>docker-compose.yml<\/code> a telep\u00edt\u00e9shez.<\/li>\n<\/ul>\n<p>\n\u00c9s az utols\u00f3 \u00e9rdekes mappa \u2014 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld_back\/tree\/master\/.ci-cd\">.ci-cd<\/a><\/noindex>. Ebben tal\u00e1lhat\u00f3k a telep\u00edt\u00e9si shell-script-ek:<\/p>\n<ul>\n<li><code>deploy.sh<\/code> \u2014 migr\u00e1ci\u00f3k \u00e9s telep\u00edt\u00e9sek ind\u00edt\u00e1sa. Ez a szerveren elindul a Github Actions-ban a tesztek futtat\u00e1sa ut\u00e1n;<\/li>\n<li><code>rollback.sh<\/code> \u2014 a kont\u00e9nerek vissza\u00e1ll\u00edt\u00e1sa a kor\u00e1bbi verzi\u00f3ra;<\/li>\n<li><code>curl_tg.sh<\/code> \u2014 \u00e9rtes\u00edt\u00e9sek k\u00fcld\u00e9se a telep\u00edt\u00e9sr\u0151l a Telegramon.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Angular front-end<\/h2>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld-front\">Repository with the front<\/a><\/noindex> is significantly simpler than the back-end. The front consists of three pages:<\/p>\n<ul>\n<li>Home page with a form to submit an email and a logout button.<\/li>\n<li>Login page.<\/li>\n<li>Registration page.<\/li>\n<\/ul>\n<p>\nThe home page looks minimalistic:<\/p>\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/4db36add2c4277397724b0d71b96ff06.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nThere are two files in the root <code>Dockerfile<\/code> \u00e9s <code>docker-compose.yml<\/code>, as well as a familiar folder <code>.ci-cd<\/code> with slightly fewer scripts than in the back-end repository (test launch scripts have been removed).<\/p>\n<h1>Starting a project in Plesk<\/h1>\n<p>\nLet\u2019s start with configuring Plesk and creating a subscription for our site.<\/p>\n<h2>Installing extensions<\/h2>\n<p>\nIn Plesk, we will need four extensions: <\/p>\n<ul>\n<li><code>Docker<\/code> for managing and visually displaying the status of containers in the Plesk admin panel;<\/li>\n<li><code>Kont\u00e9neriz\u00e1l\u00e1s<\/code> for setting the deployment step on the server;<\/li>\n<li><code>Let's Encrypt<\/code> for generating (and auto-renewing) free TLS certificates;<\/li>\n<li><code>Firewall<\/code> for filtering incoming traffic.<\/li>\n<\/ul>\n<p>\nThey can be installed via the Plesk admin panel in the Extensions section:<\/p>\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/350cf7d7ca3ae1a965a0d3f8a73594ef.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nWe will not discuss detailed configuration of the extensions; the default settings will suffice for our demo purposes.<\/p>\n<h2>Creating a subscription and a website<\/h2>\n<p>\nNext, we need to create a subscription for our site helloworld.ru and add the subdomain dev.helloworld.ru.<\/p>\n<ol>\n<li>We create a subscription for the domain helloworld.ru and specify a username-password for the system user:\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/3932dc7492aa523b6cbd540ad7a7fe6b.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nAt the bottom of the page, check the box <i>Biztos\u00edtsa a domaint a Let's Encrypt seg\u00edts\u00e9g\u00e9vel<\/i>, if we want to set up HTTPS for the site:<\/p>\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/f4d23a34764fdeb411fe2ca9cc95cb45.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>Next, in this subscription, we create the subdomain dev.helloworld.ru (for which a free TLS certificate can also be issued):\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/d57e6ba71454cb537917400de4275e92.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ol>\n<p><\/p>\n<h1>Installing server components<\/h1>\n<p>\nWe have a server with <i>OS Debian Stretch 9.12<\/i> and the control panel <i>Plesk Obsidian 18.0.27<\/i>.<\/p>\n<p>We need to install and configure for our project:<\/p>\n<ul>\n<li>PostgreSQL (in our case, there will be one server with two databases for dev- and prod-environments).<\/li>\n<li>RabbitMQ (the same, one instance with different vhosts for environments).<\/li>\n<li>Two instances of Redis (for dev- and prod-environments).<\/li>\n<li>Docker Registry (for local storage of built Docker images).<\/li>\n<li>UI interface for Docker registry.<\/li>\n<\/ul>\n<p><\/p>\n<h2>PostgreSQL<\/h2>\n<p>\nThe PostgreSQL DBMS is already included with Plesk, but not the latest version (at the time of writing this article, Plesk Obsidian <noindex><a rel=\"nofollow\" href=\"https:\/\/docs.plesk.com\/release-notes\/obsidian\/software-requirements\/\">supported<\/a><\/noindex> Postgres versions 8.4\u201310.8). We want the latest version for our application (12.3 at the time of writing), so we will install it manually.<\/p>\n<p>There are plenty of detailed instructions for installing Postgres on Debian available online (<noindex><a rel=\"nofollow\" href=\"https:\/\/tecadmin.net\/install-postgresql-on-debian-9-stretch\/\">p\u00e9ld\u00e1m<\/a><\/noindex>), so I won\u2019t describe them in detail, just provide the commands:<\/p>\n<pre><code class=\"bash\">wget -q https:\/\/www.postgresql.org\/media\/keys\/ACCC4CF8.asc -O - | sudo apt-key add -\nsudo sh -c 'echo \"deb http:\/\/apt.postgresql.org\/pub\/repos\/apt\/ stretch-pgdg main\" &gt;&gt; \/etc\/apt\/sources.list.d\/pgdg.list'\n\nsudo apt-get update\nsudo apt-get install postgresql postgresql-contrib\n<\/code><\/pre>\n<p>\nFigyelembe v\u00e9ve, hogy a PostgreSQL alap\u00e9rtelmezett be\u00e1ll\u00edt\u00e1sai meglehet\u0151sen k\u00f6zepesek, mindenk\u00e9ppen ki kell igaz\u00edtani a konfigur\u00e1ci\u00f3t. Ebben seg\u00edt nek\u00fcnk <noindex><a rel=\"nofollow\" href=\"http:\/\/pgconfigurator.cybertec.at\/\">, amely szeml\u00e9lteti, mennyit takar\u00edt meg vagy vesz\u00edt az ember, ha p\u00e9ld\u00e1ul Lausanne-b\u00f3l \u00c9cublans-ba (el\u0151v\u00e1ros, ahol az EPFL tal\u00e1lhat\u00f3) k\u00f6lt\u00f6zik.<\/a><\/noindex>: meg kell adni a saj\u00e1t szerver\u00fcnk param\u00e9tereit \u00e9s a be\u00e1ll\u00edt\u00e1sokat a <code>\/etc\/postgresql\/12\/main\/postgresql.conf<\/code>javasoltakra kell cser\u00e9lni. \u00c9rdemes megjegyezni, hogy az ilyen kalkul\u00e1torok nem csodafegyverek, \u00e9s az adatb\u00e1zist c\u00e9lzottabban kell optimaliz\u00e1lni, figyelembe v\u00e9ve a hardver\u00fcnket, az alkalmaz\u00e1st \u00e9s a lek\u00e9rdez\u00e9sek \u00f6sszetetts\u00e9g\u00e9t. De indul\u00e1snak ez elegend\u0151.<\/p>\n<p>Az aj\u00e1nlott kalkul\u00e1tor be\u00e1ll\u00edt\u00e1sain k\u00edv\u00fcl a <code>, hogy a tesztadatb\u00e1zisunk ne akarjon csendesen biztos\u00edt\u00e9kot l\u00e9trehozni.<\/code>alap\u00e9rtelmezett 5432-es portot is m\u00e1sikra kell cser\u00e9ln\u00fcnk (a mi p\u00e9ld\u00e1nkban \u2014 <strong>53983<\/strong>).<\/p>\n<p>A konfigur\u00e1ci\u00f3s f\u00e1jl m\u00f3dos\u00edt\u00e1sa ut\u00e1n \u00fajra kell ind\u00edtani a postgresql-szervert a k\u00f6vetkez\u0151 parancs haszn\u00e1lat\u00e1val:<\/p>\n<pre><code class=\"bash\">service postgresql restart\n<\/code><\/pre>\n<p>\nTelep\u00edtett\u00fck \u00e9s be\u00e1ll\u00edtottuk a PostgreSQL-t. Most l\u00e9trehozunk adatb\u00e1zisokat, felhaszn\u00e1l\u00f3kat a dev- \u00e9s prod-k\u00f6rnyezethez, \u00e9s jogokat adunk a felhaszn\u00e1l\u00f3knak az adatb\u00e1zis kezel\u00e9s\u00e9re:<\/p>\n<pre><code class=\"bash\">$ su - postgres\npostgres:~$ create database hw_dev_db_name;\nCREATE DATABASE\npostgres:~$ create user hw_dev_db_user with password 'hw_dev_db_password';\nCREATE ROLE\npostgres:~$ grant ALL privileges ON database hw_dev_db_name to hw_dev_db_user;\nGRANT\npostgres:~$ create database hw_prod_db_name;\nCREATE DATABASE\npostgres:~$ create user hw_prod_db_user with password 'hw_prod_db_password';\nCREATE ROLE\npostgres:~$ grant ALL privileges ON database hw_prod_db_name to hw_prod_db_user;\nGRANT\n<\/code><\/pre>\n<p><\/p>\n<h2>RabbitMQ<\/h2>\n<p>\nT\u00e9rj\u00fcnk \u00e1t a RabbitMQ telep\u00edt\u00e9s\u00e9re \u2014 \u00fczenetkezel\u0151 a Celery sz\u00e1m\u00e1ra. Debianon viszonylag egyszer\u0171en telep\u00edthet\u0151:<\/p>\n<pre><code class=\"bash\">wget https:\/\/packages.erlang-solutions.com\/erlang-solutions_1.0_all.deb\nsudo dpkg -i erlang-solutions_1.0_all.deb\n\nsudo apt-get update\nsudo apt-get install erlang erlang-nox\n\nsudo add-apt-repository 'deb http:\/\/www.rabbitmq.com\/debian\/ testing main'\nwget -O- https:\/\/www.rabbitmq.com\/rabbitmq-release-signing-key.asc | sudo apt-key add -\n\nsudo apt-get update\nsudo apt-get install rabbitmq-server\n<\/code><\/pre>\n<p>\nA telep\u00edt\u00e9s ut\u00e1n l\u00e9tre kell hoznunk <i>vhosts<\/i>, felhaszn\u00e1l\u00f3kat, \u00e9s meg kell adnunk a sz\u00fcks\u00e9ges jogokat:<\/p>\n<pre><code class=\"bash\">sudo rabbitmqctl add_user hw_dev_amqp_user hw_dev_amqp_password \nsudo rabbitmqctl set_user_tags hw_dev_amqp_user administrator\nsudo rabbitmqctl add_vhost hw_dev_vhost\nsudo rabbitmqctl set_permissions -p hw_dev_vhost hw_dev_amqp_user \".*\" \".*\" \".*\"\n\nsudo rabbitmqctl add_user hw_prod_amqp_user hw_prod_amqp_password \nsudo rabbitmqctl set_user_tags hw_prod_amqp_user administrator\nsudo rabbitmqctl add_vhost hw_prod_vhost\nsudo rabbitmqctl set_permissions -p hw_prod_vhost hw_prod_amqp_user \".*\" \".*\" \".*\"\n<\/code><\/pre>\n<p><\/p>\n<h2>Redis<\/h2>\n<p>\nMost telep\u00edtj\u00fck \u00e9s be\u00e1ll\u00edtjuk az utols\u00f3 komponenst az alkalmaz\u00e1sunk sz\u00e1m\u00e1ra \u2014 Redis-t. Ez a Celery feladatainak eredm\u00e9nyeinek t\u00e1rol\u00e1s\u00e1ra szolg\u00e1l\u00f3 h\u00e1ts\u00f3 rendszerk\u00e9nt fog m\u0171k\u00f6dni.<\/p>\n<p>K\u00e9t Docker-kont\u00e9nert ind\u00edtunk Redis-szal a dev- \u00e9s prod-k\u00f6rnyezetekhez a k\u00f6vetkez\u0151 kiterjeszt\u00e9s seg\u00edts\u00e9g\u00e9vel <code>Docker<\/code> a Plesk sz\u00e1m\u00e1ra.<\/p>\n<ol>\n<li>Bel\u00e9p\u00fcnk a Pleskbe, \u00e1tmegy\u00fcnk a Kiterjeszt\u00e9sek r\u00e9szlegbe, keres\u00fcnk egy Docker kiterjeszt\u00e9st, \u00e9s telep\u00edtj\u00fck (sz\u00fcks\u00e9g\u00fcnk van a ingyenes verzi\u00f3ra):\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/5638f9b40274e4f7441434279c76a426.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>\u00c1tmegy\u00fcnk a telep\u00edtett kiterjeszt\u00e9sre, \u00e9s keres\u00fcnk egy k\u00e9pet: <code>redis bitnami<\/code> \u00e9s telep\u00edtj\u00fck a legfrissebb verzi\u00f3t:\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/578bbbed6a66a60a4f7410f7d61ea542.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>Bel\u00e9p\u00fcnk a let\u00f6lt\u00f6tt kont\u00e9nerbe, \u00e9s m\u00f3dos\u00edtjuk a konfigur\u00e1ci\u00f3t: megadjuk a portot, a maxim\u00e1lis RAM m\u00e9retet, a jelsz\u00f3t a k\u00f6rnyezeti v\u00e1ltoz\u00f3kban, \u00e9s hozz\u00e1adjuk a k\u00f6tetet:\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/8bc804b794735412f5e510b3049c5667.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>A 2-3. l\u00e9p\u00e9seket v\u00e9grehajtjuk a prod-kont\u00e9nerre, csak a param\u00e9tereket m\u00f3dos\u00edtjuk: port, jelsz\u00f3, RAM m\u00e9ret \u00e9s a mappa el\u00e9r\u00e9si \u00fatja a szerveren:\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/3af50181c8b3e1ace23a8de11826cb51.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ol>\n<p><\/p>\n<h2>Docker Registry<\/h2>\n<p>\nA alap szolg\u00e1ltat\u00e1sok mellett \u00e9rdemes lenne saj\u00e1t Docker-image t\u00e1rol\u00f3t l\u00e9tes\u00edteni a szerveren. Szerencs\u00e9re a t\u00e1rhely \u00e1rak most el\u00e9g olcs\u00f3k (biztosan olcs\u00f3bb, mint a DockerHub el\u0151fizet\u00e9s), \u00e9s a priv\u00e1t t\u00e1rol\u00f3 telep\u00edt\u00e9se is nagyon egyszer\u0171. <\/p>\n<p>Azt szeretn\u00e9nk, ha a k\u00f6vetkez\u0151ket telep\u00edten\u00e9nk:<\/p>\n<ul>\n<li>jelsz\u00f3val v\u00e9dett Docker-t\u00e1rol\u00f3, amely el\u00e9rhet\u0151 aldomainen <noindex><a rel=\"nofollow\" href=\"https:\/\/docker.helloworld.ru\">https:\/\/docker.helloworld.ru<\/a><\/noindex>;<\/li>\n<li>UI fel\u00fclet az image-ek megtekint\u00e9s\u00e9re a t\u00e1rol\u00f3ban, el\u00e9rhet\u0151 a <noindex><a rel=\"nofollow\" href=\"https:\/\/docker-ui.helloworld.ru\">https:\/\/docker-ui.helloworld.ru<\/a><\/noindex>.<\/li>\n<\/ul>\n<p>\nEhhez:<\/p>\n<ol>\n<li>Hozzunk l\u00e9tre a Pleskben k\u00e9t aldomaint az el\u0151fizet\u00e9s\u00fcnk keret\u00e9ben: docker.helloworld.ru \u00e9s docker-ui.helloworld.ru, \u00e9s \u00e1ll\u00edtsuk be sz\u00e1mukra a Let\u2019s Encrypt tan\u00fas\u00edtv\u00e1nyokat.<\/li>\n<li>A docker.helloworld.ru aldomain mapp\u00e1j\u00e1ba hozz\u00e1adunk egy f\u00e1jlt: <code>docker-compose.yml<\/code> a k\u00f6vetkez\u0151 tartalommal:\n<pre><code class=\"plaintext\">version: \"3\"\n\nservices:\n  docker-registry:\n    image: \"registry:2\"\n    restart: always\n    ports:\n      - \"53985:5000\"\n    environment:\n      REGISTRY_AUTH: htpasswd\n      REGISTRY_AUTH_HTPASSWD_REALM: basic-realm\n      REGISTRY_AUTH_HTPASSWD_PATH: \/auth\/.htpasswd\n      REGISTRY_STORAGE_FILESYSTEM_ROOTDIRECTORY: \/data\n    volumes:\n      - .\/.docker-registry.htpasswd:\/auth\/.htpasswd\n      - .\/data:\/data\n\n  docker-registry-ui:\n    image: konradkleine\/docker-registry-frontend:v2\n    restart: always\n    ports:\n      - \"53986:80\"\n    environment:\n      VIRTUAL_HOST: '*, https:\/\/*'\n      ENV_DOCKER_REGISTRY_HOST: 'docker-registry'\n      ENV_DOCKER_REGISTRY_PORT: 5000\n    links:\n      - 'docker-registry'\n<\/code><\/pre>\n<p>\n<\/li>\n<li>SSH-n kereszt\u00fcl gener\u00e1ljuk a .htpasswd f\u00e1jlt a Docker-t\u00e1rol\u00f3 alap\u00fa hiteles\u00edt\u00e9shez:\n<pre><code class=\"plaintext\">htpasswd -bBc .htpasswd hw_docker_admin hw_docker_password<\/code><\/pre>\n<\/li>\n<li>\u00d6sszeszerelj\u00fck \u00e9s elind\u00edtjuk a kont\u00e9nereket:\n<pre><code class=\"plaintext\">docker-compose up -d<\/code><\/pre>\n<\/li>\n<li>Ezen k\u00edv\u00fcl ir\u00e1ny\u00edtani kell az Nginx-et a kont\u00e9nereinkre. Ezt a Plesk-en kereszt\u00fcl v\u00e9gezhetj\u00fck el. <\/li>\n<\/ol>\n<p>\nA k\u00f6vetkez\u0151 l\u00e9p\u00e9seket v\u00e9gre kell hajtani a docker.helloworld.ru \u00e9s docker-ui.helloworld.ru aldomainek eset\u00e9ben:<\/p>\n<p>A r\u00e9szben <i>Dev Tools<\/i> a weboldalunkon bel\u00e9p\u00fcnk a <i>Docker Proxy Rules<\/i>:<\/p>\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/d9c05901d95d61ce5db27a1a7cfddf49.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n\u00e9s hozz\u00e1adunk egy szab\u00e1lyt az \u00e9rkez\u0151 forgalom ir\u00e1ny\u00edt\u00e1s\u00e1ra a kont\u00e9ner\u00fcnk fel\u00e9:<\/p>\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/faa85cf6da648ef55b7c87c44040efb1.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<ol>\n<li>Ellen\u0151rizz\u00fck, hogy be tudunk-e jelentkezni a kont\u00e9ner\u00fcnkbe a helyi g\u00e9pr\u0151l:\n<pre><code class=\"plaintext\">$ docker login docker.helloworld.ru -u hw_docker_admin -p hw_docker_password\nWARNING! A --password CLI haszn\u00e1lata nem biztons\u00e1gos. Haszn\u00e1lja a --password-stdin-t.\nJelentkez\u00e9s siker\u00fclt<\/code><\/pre>\n<\/li>\n<li>Ellen\u0151rizz\u00fck a docker-ui.helloworld.ru aldomain m\u0171k\u00f6d\u00e9s\u00e9t is:\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/fdd6e1396c27c02a88bcbd7efb12f247.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nHa r\u00e1kattintunk a Browse repositories lehet\u0151s\u00e9gre, a b\u00f6ng\u00e9sz\u0151 megjelen\u00edt egy bejelentkez\u0151 ablakot, ahov\u00e1 be kell \u00edrni a repozit\u00f3rium felhaszn\u00e1l\u00f3nev\u00e9t \u00e9s jelszav\u00e1t. Ezt k\u00f6vet\u0151en \u00e1tker\u00fcl\u00fcnk a repozit\u00f3riumok list\u00e1j\u00e1n tal\u00e1lhat\u00f3 oldalra (ez egyel\u0151re \u00fcres lesz):<\/p>\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/f2d75edb530e9d746095ae02d7793c1f.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ol>\n<p><\/p>\n<h2>Portok megnyit\u00e1sa a Plesk T\u0171zfalban<\/h2>\n<p>\nA komponensek telep\u00edt\u00e9se \u00e9s be\u00e1ll\u00edt\u00e1sa ut\u00e1n nyitnunk kell portokat, hogy a komponensek el\u00e9rhet\u0151k legyenek a Docker kont\u00e9nerekb\u0151l \u00e9s a k\u00fcls\u0151 h\u00e1l\u00f3zatb\u00f3l.<\/p>\n<p>N\u00e9zz\u00fck meg, hogyan csin\u00e1ljuk ezt a kor\u00e1bban telep\u00edtett Plesk T\u0171zfal b\u0151v\u00edtm\u00e9ny p\u00e9ld\u00e1j\u00e1n.<\/p>\n<ol>\n<li>L\u00e9pj\u00fcnk a k\u00f6vetkez\u0151re <i>Eszk\u00f6z\u00f6k &amp; Be\u00e1ll\u00edt\u00e1sok &gt; Be\u00e1ll\u00edt\u00e1sok &gt; T\u0171zfal<\/i>:<br \/>\n<img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/d54b4941944fe191574472a475cbaebe.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>L\u00e9pj\u00fcnk a k\u00f6vetkez\u0151re <i>Plesk T\u0171zfal Szab\u00e1lyok m\u00f3dos\u00edt\u00e1sa &gt; Egy\u00e9ni szab\u00e1ly hozz\u00e1ad\u00e1sa<\/i> \u00e9s nyissuk meg az al\u00e1bbi TCP portokat a Docker alh\u00e1l\u00f3zat sz\u00e1m\u00e1ra (<strong>172.0.0.0\/8)<\/strong>:<br \/>\nRabbitMQ: 1883, 4369, 5671-5672, 25672, 61613-61614<br \/>\nRedis: 32785, 32786<\/p>\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/3359845f9bd6dc303274da737d4b27a2.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>Ezen k\u00edv\u00fcl adjunk hozz\u00e1 egy szab\u00e1lyt, amely megnyitja a PostgreSQL \u00e9s a RabbitMQ kezel\u0151fel\u00fclet portjait a k\u00fcls\u0151 vil\u00e1g sz\u00e1m\u00e1ra:\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/f812cfc7127da469507538ea48b2c80d.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>Alkalmazzuk a szab\u00e1lyokat az Apply Changes gomb seg\u00edts\u00e9g\u00e9vel:\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/e85444ae717aaefa796664003fc86578.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<\/ol>\n<p><\/p>\n<h1>CI\/CD be\u00e1ll\u00edt\u00e1sa a Github Actions-ban<\/h1>\n<p>\nV\u00e1gjunk bele a leg\u00e9rdekesebb r\u00e9szbe \u2014 a folyamatos integr\u00e1ci\u00f3s \u00e9s sz\u00e1ll\u00edt\u00e1si folyamat be\u00e1ll\u00edt\u00e1s\u00e1ba a projekt\u00fcnkh\u00f6z.<\/p>\n<p>Ez a folyamat k\u00e9t r\u00e9szre oszlik: <\/p>\n<ul>\n<li>a k\u00e9p l\u00e9trehoz\u00e1sa \u00e9s a tesztek futtat\u00e1sa (a h\u00e1tt\u00e9rben) \u2014 a Github oldal\u00e1n;<\/li>\n<li>a migr\u00e1ci\u00f3k v\u00e9grehajt\u00e1sa (a h\u00e1tt\u00e9rben) \u00e9s a kont\u00e9nerek telep\u00edt\u00e9se \u2014 a szerveren.<\/li>\n<\/ul>\n<p><\/p>\n<h2>Telep\u00edt\u00e9s Plesk-ben<\/h2>\n<p>\nEl\u0151sz\u00f6r n\u00e9zz\u00fck meg a m\u00e1sodik pontot (mivel az els\u0151t\u00f3l f\u00fcgg).<\/p>\n<p>A telep\u00edt\u00e9si folyamatot a Git b\u0151v\u00edtm\u00e9ny seg\u00edts\u00e9g\u00e9vel fogjuk be\u00e1ll\u00edtani a Plesk-ben.<\/p>\n<p>Vizsg\u00e1ljuk meg a Backend repozit\u00f3rium Prod k\u00f6rnyezet\u00e9nek p\u00e9ld\u00e1j\u00e1t.<\/p>\n<ol>\n<li>L\u00e9pj\u00fcnk be a Helloworld webhely el\u0151fizet\u00e9s\u00e9be, \u00e9s navig\u00e1ljunk a Git szekci\u00f3ba:\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/b55b371560ea87a2954b6553a7cefc49.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>Az \"Remote Git repository\" mez\u0151be beillesztj\u00fck a GitHub repozit\u00f3riumunk linkj\u00e9t, \u00e9s megv\u00e1ltoztatjuk az alap\u00e9rtelmezett mapp\u00e1t <code>httpdocs<\/code> egy m\u00e1sikra (p\u00e9ld\u00e1ul, <code>\/httpdocs\/hw_back<\/code>):\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/db9ba9adb6e2e1bed5da7ae8e88c76e1.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>M\u00e1soljuk \u00e1t a SSH nyilv\u00e1nos kulcsot az el\u0151z\u0151 l\u00e9p\u00e9sb\u0151l, \u00e9s <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/settings\/ssh\/new\">hozz\u00e1adjuk<\/a><\/noindex> azt a Github be\u00e1ll\u00edt\u00e1sain\u00e1l.<\/li>\n<li>Nyomjuk meg az OK gombot a 2. pontn\u00e1l, ezut\u00e1n egyb\u0151l a Plesk repozit\u00f3rium oldal\u00e1ra ker\u00fcl\u00fcnk. Most be kell \u00e1ll\u00edtanunk a repozit\u00f3rium friss\u00edt\u00e9s\u00e9t a master \u00e1gba t\u00f6rt\u00e9n\u0151 elk\u00f6telez\u00e9sekkor. Ehhez l\u00e9pj\u00fcnk a <i>Repozit\u00f3rium be\u00e1ll\u00edt\u00e1sai<\/i> \u00e9s ments\u00fck el a k\u00f6vetkez\u0151 \u00e9rt\u00e9ket: <code>Webhook URL<\/code> (ez sz\u00fcks\u00e9ges lesz k\u00e9s\u0151bb a Github Actions be\u00e1ll\u00edt\u00e1sakor):\n<p><img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/14d48a357f821d734d40dc434ab3682a.png\" style=\"display:block;margin: 0 auto;\" \/><\/li>\n<li>Az el\u0151z\u0151 pont k\u00e9perny\u0151j\u00e9n az Actions mez\u0151be be\u00edrjuk a telep\u00edt\u00e9s ind\u00edt\u00e1s\u00e1hoz sz\u00fcks\u00e9ges scriptet:\n<pre><code class=\"plaintext\">cd {REPOSITORY_ABSOLUTE_PATH}\n.ci-cd\/deploy.sh {ENV} {DOCKER_REGISTRY_HOST} {DOCKER_USER} {DOCKER_PASSWORD} {TG_BOT_TOKEN} {TG_CHAT_ID} <\/code><\/pre>\n<p>\nahol: <\/p>\n<p><code>{REPOSITORY_ABSOLUTE_PATH}<\/code> \u2014 a prod backend repozit\u00f3rium mapp\u00e1ja a szerveren;<br \/>\n<code>{ENV}<\/code> \u2014 k\u00f6rnyezet (dev\/prod), eset\u00fcnkben <code>prod<\/code>;<br \/>\n<code>{DOCKER_REGISTRY_HOST}<\/code> \u2014 a docker repozit\u00f3riumunk hostja;<br \/>\n<code>{TG_BOT_TOKEN}<\/code> \u2014 a Telegram bot tokenje;<br \/>\n<code>{TG_CHAT_ID}<\/code> \u2014 a chat\/csatorna ID a \u00e9rtes\u00edt\u00e9sek k\u00fcld\u00e9s\u00e9re.<\/p>\n<p>Script p\u00e9lda:<\/p>\n<pre><code class=\"plaintext\">cd \/var\/www\/vhosts\/helloworld.ru\/httpdocs\/hw_back\/\n.ci-cd\/deploy.sh dev docker.helloworld.ru docker_user docker_password 12345678:AAbcdEfghCH1vGbCasdfSAs0K5PALDsaw -1001234567890<\/code><\/pre>\n<\/li>\n<li>Felhaszn\u00e1l\u00f3 hozz\u00e1ad\u00e1sa a Docker csoporthoz (hogy kezelni tudja a kont\u00e9nereket) a feliratkoz\u00e1sunk alapj\u00e1n:\n<pre><code class=\"plaintext\">sudo usermod -aG docker helloworld_admin<\/code><\/pre>\n<\/li>\n<\/ol>\n<p>\nA Dev-k\u00f6rnyezet a backend-repozit\u00f3rium \u00e9s a frontend eset\u00e9ben hasonl\u00f3an van be\u00e1ll\u00edtva.<\/p>\n<h2>Pipeline telep\u00edt\u00e9se a Github Actions-ban<\/h2>\n<p>\nT\u00e9rj\u00fcnk \u00e1t a CI\/CD pipeline els\u0151 r\u00e9sz\u00e9nek be\u00e1ll\u00edt\u00e1s\u00e1ra a Github Actions-ban.<\/p>\n<h3>Backend<\/h3>\n<p>\nA pipeline le\u00edr\u00e1sa a <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld_back\/blob\/master\/.github\/workflows\/deploy.yml\">deploy.yml f\u00e1jlban tal\u00e1lhat\u00f3.<\/a><\/noindex>. <\/p>\n<p>De a r\u00e9szletez\u00e9s el\u0151tt t\u00f6lts\u00fck ki a sz\u00fcks\u00e9ges Secret v\u00e1ltoz\u00f3kat a Github-ban. Ehhez navig\u00e1ljunk a <i>Be\u00e1ll\u00edt\u00e1sok -&gt; Titkok k\u00f6z\u00f6tt.<\/i>:<\/p>\n<ul>\n<li><code>DOCKER_REGISTRY<\/code> \u2014 a Docker-repozit\u00f3riumunk hosztja (docker.helloworld.ru);<\/li>\n<li><code>DOCKER_LOGIN<\/code> \u2014 a Docker-repozit\u00f3rium hozz\u00e1f\u00e9r\u00e9si neve;<\/li>\n<li><code>DOCKER_PASSWORD<\/code> \u2014 jelszava;<\/li>\n<li><code>DEPLOY_HOST<\/code> \u2014 a Plesk adminisztr\u00e1ci\u00f3s fel\u00fclet\u00e9nek hosztja (p\u00e9lda: <noindex><a rel=\"nofollow\" href=\"https:\/\/helloworld.ru\">helloworld.ru<\/a><\/noindex>:8443 vagy <noindex><a rel=\"nofollow\" href=\"http:\/\/123.4.56.78\">123.4.56.78<\/a><\/noindex>:8443);<\/li>\n<li><code>DEPLOY_BACK_PROD_TOKEN<\/code> \u2014 a prod-repozit\u00f3riumba val\u00f3 telep\u00edt\u00e9shez sz\u00fcks\u00e9ges token (ezt a Plesk telep\u00edt\u00e9si \u00fatmutat\u00f3 4. pontj\u00e1ban kaptuk);<\/li>\n<li><code>DEPLOY_BACK_DEV_TOKEN<\/code> \u2014 a dev-repozit\u00f3riumba val\u00f3 telep\u00edt\u00e9shez sz\u00fcks\u00e9ges token.<\/li>\n<\/ul>\n<p>\nA telep\u00edt\u00e9si folyamat egyszer\u0171 \u00e9s h\u00e1rom f\u0151 l\u00e9p\u00e9sb\u0151l \u00e1ll: <\/p>\n<ul>\n<li>a k\u00e9pf\u00e1jl \u00f6sszeszerel\u00e9se \u00e9s publik\u00e1l\u00e1sa a repo-nkban;<\/li>\n<li>tesztek futtat\u00e1sa a kont\u00e9nerben az \u00fajonnan \u00f6sszeszerelt k\u00e9pf\u00e1jl alapj\u00e1n;<\/li>\n<li>telep\u00edt\u00e9s a sz\u00fcks\u00e9ges k\u00f6rnyezetbe a v\u00e1lasztott \u00e1gt\u00f3l f\u00fcgg\u0151en (dev\/master).<\/li>\n<\/ul>\n<p><\/p>\n<h3>Frontend<\/h3>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld-front\/blob\/master\/.github\/workflows\/deploy.yml\">A deploy.yml f\u00e1jl a frontend rep\u00f3n\u00e1l<\/a><\/noindex> nem sokban k\u00fcl\u00f6nb\u00f6zik a backend-t\u0151l. Ebben hi\u00e1nyzik a tesztfut\u00e1s l\u00e9p\u00e9s \u00e9s megv\u00e1ltoznak a telep\u00edt\u00e9si tokenek nevei. A frontend rep\u00f3 titkait k\u00fcl\u00f6n kell kit\u00f6lteni.<\/p>\n<h1>Webhely be\u00e1ll\u00edt\u00e1sa<\/h1>\n<p><\/p>\n<h2>A forgalom \u00e1tir\u00e1ny\u00edt\u00e1sa az Nginx-en kereszt\u00fcl<\/h2>\n<p>\nNos, most a v\u00e9g\u00e9re \u00e9rt\u00fcnk. M\u00e1r csak az sz\u00fcks\u00e9ges, hogy be\u00e1ll\u00edtsuk a bej\u00f6v\u0151 \u00e9s kimen\u0151 forgalom \u00e1tir\u00e1ny\u00edt\u00e1s\u00e1t a kont\u00e9ner\u00fcnkbe Nginx-en kereszt\u00fcl. Ezt a folyamatot m\u00e1r megtanultuk a Docker Registry 5. pontj\u00e1ban. Ugyanezt meg kell ism\u00e9telni a backend \u00e9s frontend eset\u00e9ben a dev \u00e9s prod k\u00f6rnyezetekben.<\/p>\n<p>Megmutatom a be\u00e1ll\u00edt\u00e1sok k\u00e9perny\u0151k\u00e9peit.<\/p>\n<h3>Backend<\/h3>\n<p>\n<img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/f3c38dc1c25b648db000c72ef2d30b2a.png\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<h3>Frontend<\/h3>\n<p>\n<img decoding=\"async\" alt=\"CI\/CD a Github Actions-ben Flask+Angular projekt sz\u00e1m\u00e1ra\" src=\"\/wp-content\/uploads\/2020\/06\/35d4d8ef3489608db1e173b7f214ca03.png\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<strong>Fontos pontos\u00edt\u00e1s<\/strong>. A frontend kont\u00e9nerbe minden URL \u00e1tir\u00e1ny\u00edt\u00e1sra ker\u00fcl, kiv\u00e9ve azokat, amelyek a k\u00f6vetkez\u0151vel kezd\u0151dnek: <code>\/api\/<\/code> \u2014 ezek \u00e1tir\u00e1ny\u00edt\u00e1sra ker\u00fclnek a backend kont\u00e9nerbe (ez\u00e9rt <strong>a backend kont\u00e9nerben minden handlernek a k\u00f6vetkez\u0151vel kell kezd\u0151dnie: <\/strong><strong><code>\/api\/<\/code><\/strong>).<\/p>\n<h2>\u00d6sszegz\u00e9s<\/h2>\n<p>\nMost a webhely\u00fcnknek el\u00e9rhet\u0151v\u00e9 kell v\u00e1lnia a helloworld.ru \u00e9s dev.helloworld.ru c\u00edmen (a prod \u00e9s dev k\u00f6rnyezetek megfelel\u0151en).<\/p>\n<p>\u00d6sszess\u00e9g\u00e9ben megtanultuk, hogyan k\u00e9sz\u00edthet\u00fcnk egy egyszer\u0171 alkalmaz\u00e1st Flask \u00e9s Angular haszn\u00e1lat\u00e1val, \u00e9s hogyan \u00e1ll\u00edthatunk be egy pipeline-t a Github Actions-ban a kiszolg\u00e1l\u00f3ra val\u00f3 feltelep\u00edt\u00e9shez Plesk ir\u00e1ny\u00edt\u00e1sa alatt.<\/p>\n<p>Megosztom a k\u00f3d rep\u00f3ira mutat\u00f3 linkeket: <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld_back\">h\u00e1tt\u00e9r<\/a><\/noindex>, <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/olegborzov\/helloworld-front\">frontend<\/a><\/noindex>.<br \/>\n<br \/>Forr\u00e1s: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/domclick\/blog\/506802\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u0441\u0432\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 CI\/CD \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f Plesk \u0438 Github Actions. \u0421\u0435\u0433\u043e\u0434\u043d\u044f \u0431\u0443\u0434\u0435\u043c \u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0434\u0435\u043f\u043b\u043e\u0438\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u0435\u043d\u044c\u043a\u0438\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 \u043d\u0435\u0437\u0430\u043c\u044b\u0441\u043b\u043e\u0432\u0430\u0442\u044b\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c \u00abHelloworld\u00bb. \u041e\u043d \u043d\u0430\u043f\u0438\u0441\u0430\u043d \u043d\u0430 Python-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435 Flask, \u0441 \u0432\u043e\u0440\u043a\u0435\u0440\u0430\u043c\u0438 \u043d\u0430 Celery \u0438 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u043e\u043c \u043d\u0430 Angular 8. \u0421\u0441\u044b\u043b\u043a\u0438 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438: \u0431\u044d\u043a\u0435\u043d\u0434, \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434. \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0442\u0430\u0442\u044c\u0438 \u043c\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043d\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":85647,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-85646","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u0441\u0432\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/ci-cd-v-github-actions-dlya-proekta-na-flask-angular\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"hu_HU\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47CI\/CD \u0432 Github Actions \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 Flask+Angular | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u0441\u0432\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/ci-cd-v-github-actions-dlya-proekta-na-flask-angular\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-06-17T23:42:15+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-06-17T23:42:15+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47CI\/CD a Github Actions-ban Flask+Angular projekthez | ProHoster","description":"Ebben a cikkben megosztom tapasztalataimat.","canonical_url":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/ci-cd-v-github-actions-dlya-proekta-na-flask-angular","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"hu_HU","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47CI\/CD \u0432 Github Actions \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 Flask+Angular | ProHoster","og:description":"\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u043f\u043e\u0434\u0435\u043b\u044e\u0441\u044c \u0441\u0432\u043e\u0438\u043c \u043e\u043f\u044b\u0442\u043e\u043c.","og:url":"https:\/\/prohoster.info\/hu\/blog\/administrirovanie\/ci-cd-v-github-actions-dlya-proekta-na-flask-angular","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-06-17T23:42:15+00:00","article:modified_time":"2020-06-17T23:42:15+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"85646","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 13:12:50","updated":"2022-09-29 06:56:26","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts\/85646","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/comments?post=85646"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/posts\/85646\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/media\/85647"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/media?parent=85646"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/categories?post=85646"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/hu\/wp-json\/wp\/v2\/tags?post=85646"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}