development https://www.drupal.cz/stitky/development cs Levný Continuous deployment pro Drupal 8 https://www.drupal.cz/navody/levny-continuous-deployment-pro-drupal-8 <span class="field field--name-title field--type-string field--label-hidden">Levný Continuous deployment pro Drupal 8</span> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><a title="Zobrazit profil uživatele." href="/user/martinklima" class="username">martin_klima</a></span> <span class="field field--name-created field--type-created field--label-hidden">Ne, 12/09/2018 - 19:52</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><h2><span>Motivace</span></h2> <p><span>Vývojář projektů na Drupalu 8 si vždy časem musí položit klasické otázky</span><span> </span><span>“Kam</span><span> s tím?”,</span><span> </span><span>“Jak</span><span> to tam dostat?” a</span><span> </span><span>“Jak</span><span> to tam snadno aktualizovat?”. </span></p> <p><span>První otázka směřuje k nalezení vhodného hostingu. Vhodných hostingů pro Drupal 8 je řada a nejlepší praxí je vyzkoušet či se zeptat. O tom tento článek není.</span></p> <p><span>Druhá otázka směřuje k nalezení cesty, jak projekt z tepla vašeho domácího vývojového počítače dostat k někomu cizímu do datacentra, lépe řečeno nahrát na internet, kde ho mohou najít potenciální čtenáři, návštěvníci a zákazníci. Třetí otázka se věnuje nalezení co nejjednoduššího způsobu, jak tuto činnost dělat opakovaně. Druhé a třetí otázce se věnuje tento článek.</span></p> <h3><span>Klasická cesta je trnitá</span></h3> <p><span>Drupal 8 obsahuje po základní instalaci přes 27 tisíc souborů. Klasická cesta - zkopírovat tento balík na hosting přes </span><span>SFTP nebo zastaralé FTP -</span><span> se stala utrpením na několik desítek minut. Musíte si na serveru nastavit settings.php s heslem k databázi a pak si hlídat, abyste si ho příště nepřehráli. Když pak něco opravíte</span><span> </span><span>(text</span><span> v modulu, barvu v CSS, změníte logo a změníte pořadí polí u článků...), musíte najít 3 místa, která </span><span>se změnila,</span><span> a ta nahrát na server na správná místa a nesplést se a tu změnu pořadí naklikat na serveru znovu... </span></p> <p><span>Když vám řeknu, že přenést jakoukoliv změnu Drupal projektu na internet lze pokaždé udělat jediným příkazem, zabere to několik sekund a stačí vám k tomu hosting za tři stovky měsíčně, zajímá vás jak? Super. Naučím vás to.</span></p> <h3><span>Cesta profesionálů</span></h3> <p><span>Zkušení vývojáři pracují většinou v týmech a používají určitý postup práce, kterým si zajišťují, že změny od jednoho kolegy se dostanou na počítače dalších kolegů, a tím pádem všichni pracují na stejné verzi projektu, i když je vyvíjen na několika místech paralelně. Jde tedy o distribuci aktuálního stavu projektu mezi různými počítači. My si můžeme náš hosting představit jako dalšího člena týmu, a to platí pro dvoučlenné i desetičlenné týmy. Musíme tedy požadovat, aby náš hosting </span><span>podporoval</span><span> to, co má na počítači každý člen profesionálního týmu:</span></p> <ul><li><span>SSH přístup</span></li> <li><span>Composer</span></li> <li><span>Drush</span></li> <li><span>Git</span></li> </ul><p><span>Pokud váš hosting tyto parametry má, můžete tuto kapitolu přeskočit. Většina levných hostingů, kde nejste tzv. root</span><span> </span><span>(superuživatel</span><span> se všemi právy a zodpovědností), tyto požadaky nesplňuje. Např. Český hosting má na </span><span><span>VMS</span></span><span> </span><span>(Virtual</span><span> Managed Server) všechno mimo Git. SnackHost Cloudhosting má všechno, ale Drupal 8 mi tam běží pomalu. Hostingy, které toto splňují, vám většinou pronajmou virtuální počítač s Linuxem a vyžadují, abyste byli root, vše si instalovali sami a byl z vás specialista na Linuxový server. S tím souvisí i to, že se musíte starat o bezpečnost a aktualizovat operační systém, kdykoliv se objeví nějaká bezpečnostní skulina. Specializované zahraniční hostingy pro Drupal jsou super, ale neúměrně drahé. Hosting, na kterém bych nemusel být root a který by měl k dispozici všechny nástroje pro vývojáře, jsem hledal dlouho a to hledání bylo plné zklamání. Až jsem objevil službu, která to zvládla a moje Drupal projekty tam sviští k naprosté spokojenosti za necelá 3 kila měsíčně.</span></p> <h2><span>Cloudways</span></h2> <p><span>Než budeme pokračovat, prohlašuji, že se polečností nemám žádný vztah a tento článek pouze reflektuje moje osobní zkušenosti a nenesu zodpovědnost v případě, že vaše zkušenosti budou jiné. Níže jsou uvedeny 2 odkazy. První obsahuje affiliate identifikátor; pokud na něj kliknete a já bych z toho někdy měl nějaký finanční prospěch, čestně prohlašuji, že ho rád a transparentně věnuji české Drupal asociaci na podporu české Drupal komunity. Druhý odkaz je bez identifikátoru a použijte ho v případě, že chcete mít naprostou jistotu, že ani já ani česká Asociace pro Drupal z toho nic mít nebude.</span></p> <p><a href="https://www.cloudways.com/en/drupal-cloud-hosting.php?id=255492&amp;amp;a_bid=a8d5bda6"><code><span>Cloudways - Faster Drupal Hosting</span></code></a><code><span> (stránka věnovaná hostingu pro Drupal)</span></code></p> <p><a href="https://www.cloudways.com"><code><span>Cloudways</span></code></a><code><span> - hlavní stránka</span></code></p> <p><span>Klikněte a vytvořte si testovací účet zdarma. Je omezený na 3 dny. Nejprve si založte server. Dejte mu jméno, zadejte druh a název aplikace. Na každém serveru můžete mít více tzv. aplikací, což jsou vlastně hostingy pro jednotlivé domény. Váš Drupal 8 projekt je tedy z hlediska Cloudways aplikací. Ač můžete vybrat, že chcete založit Drupal 8 aplikaci, doporučuji vám zakládat Drupal projekty jako</span><span> </span><span>“PHP</span><span> Custom App”, protože nechcete nic předinstalovávat. Vyberte si, kde váš server bude ležet. Z hlediska ceny doporučuji DigitalOcean s 1 GB RAM za 10 dolarů měsíčně a klikněte na "Launch now". K tomuto serveru budete přistupovat přes službu Cloudways, která server nakonfiguruje a poskytne webové administrační rozhraní. Za pár minut je vše připraveno. </span></p> <p><span>P</span><span><em>ozn.: Jelikož já už server mám, nevím přesně, jak jdou úkony po sobě, když se zakládá nový server, proto prosím použijte přirozenou inteligenci a zorientujte se v ovládání Cloudways, případně použijte rozsáhlou nápovědu.</em></span></p> <p><img alt="" src="https://photos-1.dropbox.com/t/2/AABjA8prG_YxGH8-ul5-Lmt-Wl6NvkVcVAx2t2P5rFcnSw/12/83194090/png/2048x1/5/1544554800/0/10/image.png/_/png%2520https%253A%252F%252Fd2mxuefqeaa7sj.cloudfront.net%252Fs_307FD49C2C6A4649BC955C880CC876C12CC1844082F6BC0A281B5652C466F67B_1543782138363_file.png?preserve_transparency=1&amp;size=2048x1&amp;size_mode=5" /></p> <p><span>Pár důležitých míst v administraci:</span></p> <h3><span>Server management</span></h3> <p><span>V záložce </span><span><em>Master credentials</em></span><span> si nahrajte </span><span><span>SSH klíč</span></span><span> a podívejte se, jakou máte IP adresu. SSH klíčů se nebojte, složitě to jen vypadá a ušetří to mnoho času, protože místo zadávání hesla vás server pozná podle klíče. Pokud potřebujete, podívejte se na nápovědu, třeba na GitHubu </span><span><a href="https://help.github.com/articles/connecting-to-github-with-ssh">https://help.github.com/articles/connecting-to-github-with-ssh</a></span><span>. Pokud byste to z nějakého důvodu odmítali, je samozřejmě možnost ponechat autentizaci na klasických metodách pomocí jména a hesla.</span></p> <h3><span>Aplication management</span></h3> <p><span>V záložce </span><span><em>Access detail</em></span><span> máte přidělenou testovací URL adresu pro váš web a můžete si nastavit heslo k databázi.</span></p> <p><span>V záložce </span><span><em>Application Settings</em></span><span> si nastavte položku Folder na název projektu</span><span> </span><span>(d8workshop).</span><span> Je to název adresáře a pomůže vám to v orientaci. Soubory projektu pak snadno najdete v adresáři </span><span><strong>~/applications/d8workshop/public_html</strong></span><span>. Tuto cestu budete potřebovat znát.</span></p> <p><span><span><img alt="" height="287" src="https://d2mxuefqeaa7sj.cloudfront.net/s_307FD49C2C6A4649BC955C880CC876C12CC1844082F6BC0A281B5652C466F67B_1543785494473_file.png" width="234" /></span></span></p> <p><span>Jakmile máte vytvořený hosting pro váš projekt, můžeme se konečně dostat k návodu na deployment.</span></p> <p> </p> <h2><span>Deployment - potřebné znalosti a dovednosti</span></h2> <p><span>Tento článek předpokládá, že toto máte a znáte:</span></p> <ul><li><span>Práci s Gitem - nemusíte umět Git příkazy, pokud máte grafickou aplikaci pro práci s gitem. Já budu uvádět příkazy a vy si najděte, jak se to ve vaší aplikaci dělá.</span></li> <li><span>Základní práci s Composerem - ten nám bude nahrávat Drupal, moduly a závislosti.</span></li> <li><span>Drush - budu používat Drush příkazy, protože je to jednodušší a protože jsme přece profíci, ne?</span></li> <li><span>Prostředí příkazové řádky - budete na serveru pracovat vzdáleně, takže abyste chápali, co děláte</span><span> </span><span>(cd,</span><span> ls, mkdir apod...)</span></li> <li><span>SSH klíč - předpokládám, že máte SSH klíč, jehož veřejnou část jste nahráli na server.</span></li> <li><span>Umíte nainstalovat Drupal, chápete config management a další základní věci, které byly např. předmětem workshopu Radima Klašky, který můžete najít na </span><span><a href="https://github.com/Drupalcz/workshop">https://github.com/Drupalcz/workshop</a></span><span> a v README.md je návod, jak nainstalovat Drupal projekt. V tomto návodu budeme s projektem z tohoto repozitáře pracovat. Avšak můžete pracovat i se svým vlastním či jiným existujícím projektem.</span></li> <li><span>Máte na svém počítači rozběhnutý projekt z výše uvedeného bodu.</span></li> </ul><h2><span>Jak na to</span></h2> <p><span>Naším cílem je vytvořit si na Cloudways serveru vzdálený git repozitář a nakonfigurovat ho tak, aby jakmile přijme nějaké změny, přenesl automaticky tyto změny do prostoru webhostingu a provedl instalační příkazy.</span></p> <h3><span>SSH připojení</span></h3> <p><span>Nejprve si nakonfigurujeme SSH spojení, abychom nemuseli zadávat heslo a nic nás nezdržovalo. Najděte v domácím adresáři soubor </span><span><em>.ssh/config</em></span><span> a vložte do něj</span></p> <p><code><span>Host </span><span><span>cloudways</span></span></code></p> <p><code><span>    Hostname </span><span><strong>ip_vašeho_serveru</strong></span></code></p> <p><code><span>    User </span><span><strong>master_login_username</strong></span></code></p> <p><span>Název serveru si vymyslete podle potřeby, já jsem použil</span><span> </span><span>“cloudways”.</span><span> Uživatelské jméno a IP adresu  najdete v záložce <em>Server management</em> - <em>Master credentials</em>. Uložte a pak napište do terminálu:</span></p> <p><code><span>ssh cloudways</span></code></p> <p><span>...a měli byste tam být.</span></p> <h2><span>Vzdálený git repozitář</span></h2> <p><span>Nyní vytvoříme vzdálený git repozitář v adresáři </span><span><strong>git_repos</strong></span><span>. Je dobrým zvykem pojmenovávat repozitáře s příponou .git. Git repozitář je technicky vzato adresář, takže ten v našem návodu pojmenujeme </span><span><strong>d8workshop.git</strong></span><span>. Tento repozitář bude přijímat naše změny jako pomyslný</span><span> </span><span>“další</span><span> člen našeho týmu”. Na vzdáleném serveru:</span></p> <p><code><span>mkdir git_repos</span></code></p> <p><code><span>cd git_repos</span></code></p> <p><code><span>mkdir d8workshop.git</span></code></p> <p><code><span>cd d8workshop.git</span></code></p> <p><code><span>git init --bare</span></code></p> <p><span>Posledním příkazem jsme vytvořili strukturu prázdného </span><span>git</span><span> repozitáře a měli bychom vidět zprávu:</span></p> <p><code><span>Initialized empty Git repository in /home/master/git_repos/d8workshop.git/</span></code></p> <p> </p> <h2><span>Vytvoření sluhy</span></h2> <p><span>Vytvoříme si v adresáři </span><span><strong>hooks</strong></span><span> věrného sluhu. Ten nikdy nespí a čeká, až se v repozitáři něco nového objeví. Jakmile zahlédne změnu, všechny soubory v repozitáři vykopíruje na náš hosting, což je technicky jen jiný adresář, a provede sérii příkazů k instalaci změn do našeho Drupal projektu. Nejprve si vzpomeňte, že adresář s aplikací</span><span> </span><span>(hostingem)</span><span> je </span><span><strong>~/applications/d8workshop/public_html</strong></span><span>.</span></p> <p> </p> <p><span>Vytvoření nového souboru post-receive. Na vzdáleném serveru:</span></p> <p><code><span>cd hooks</span></code></p> <p><code><span>nano post-receive</span></code></p> <p> </p> <p><span>Do otevřeného editoru vložte:</span></p> <p><code><span>#!/bin/bash</span></code></p> <p><code><span>GIT_DIR="/home/master/git_repos/d8workshop.git"</span></code></p> <p><code><span>TARGET="/home/master/applications/d8workshop/public_html"</span></code></p> <p><code><span>BRANCH="master"</span></code></p> <p> </p> <p><code><span>while read oldrev newrev ref</span></code></p> <p><code><span>do</span></code></p> <p><code><span>        # only checking out the specified branch you would like to deploy</span></code></p> <p><code><span>        if [[ $ref = refs/heads/$BRANCH ]];</span></code></p> <p><code><span>        then</span></code></p> <p><code><span>                echo "Ref $ref received. Deploying ${BRANCH} branch to ${TARGET}..."</span></code></p> <p><code><span>                git --git-dir=$GIT_DIR --work-tree=$TARGET checkout ${BRANCH} -f</span></code></p> <p><code><span>                # You will place more commands HERE...</span></code></p> <p><code><span>                echo "Finished."</span></code></p> <p><code><span>        else</span></code></p> <p><code><span>                echo "Ref $ref received. Only the ${BRANCH} branch may be deployed on this server."</span></code></p> <p><code><span>        fi</span></code></p> <p><code><span>done</span></code></p> <p><span>Uložte a zavřete</span><span> </span><span>(Ctrl+O,</span><span> Enter, Ctrl-X). Náš sluha čeká, zda byla přijata změna ve větvi</span><span> </span><span>(branch)</span><span> </span><span>“master”.</span><span> Pokud ano, vykopíruje všechny soubory do adresáře TARGET a pomocí parametru</span><span> </span><span>-f</span><span> přepíše vše již existující. Zatím nepřidáváme žádné instalační příkazy. Aby sluha ožil, musíme ho označit jako spustitelný soubor.</span></p> <p><code><span>chmod +x post-receive</span></code></p> <h2><span>Propojení projektu se vzdáleným repozitářem</span></h2> <p><span>Náš workshopový projekt má svůj repozitář na Githubu, odkud jsme ho získali příkazem "git clone", ale tím také vznikl lokální git repozitář přímo v adresáři projektu, pojmenovaný jako</span><span> </span><span>“.git”.</span><span> Na našem serveru máme třetí repozitář. Každý z těchto repozitářů ukazuje v praxi základní vlastnost gitu, což je decentralizovanost repozitářů, a každý repozitář představuje geograficky oddělenou zálohu našeho projektu, což je dobrý bonus. Nyní propojíme lokální repozitář s tím vzdáleným na našem serveru. Následující příkaz informuje lokální repozitář, že přidáváme  jeden nový vzdálený.</span></p> <p><code><span>git remote add cloudways </span><span>master</span><span>_xxx@cloudways:/home/master/git_repos/d8workshop.git</span></code></p> <p><span>První výskyt slova</span><span> </span><span>“cloudways”</span><span> je název vzdáleného </span><span>repozitáře</span><span>. Můžete si tam dát co chcete, třeba i</span><span> </span><span>“sluha”.</span><span> Slovo</span><span> </span><span>“</span><span>master</span><span>_xxx@cloudways”</span><span> znamená, že se připojujete jako uživatel </span><span><em>master</em></span><span><em>_xxx</em></span><span> na server </span><span><em>cloudways</em></span><span>, což je označení serveru, který jste definovali v souboru </span><span><em>.ssh/config</em></span><span>. Text</span><span> </span><span>“/home/master/git_repos/d8workshop.git”</span><span> je cesta k repozitáři na vzdáleném serveru. Příkaz</span><span> </span><span>“git</span><span> remote add” nekontroluje, zda je vzdálený repozitář dosažitelný, takže pokud jste udělali nějakou chybu, nedozvíte se to. Proto použijte příkaz:</span></p> <p><code><span>git remote show cloudways</span></code></p> <p> </p> <p><code><span>* remote cloudways</span></code></p> <p><code><span>  Fetch URL: master_dhtpbbmznk@cloudways:/home/master/git_repos/d8workshop.git</span></code></p> <p><code><span>  Push  URL: master_dhtpbbmznk@cloudways:/home/master/git_repos/d8workshop.git</span></code></p> <p><code><span>  HEAD branch: (unknown)</span></code></p> <p> </p> <p><span>pro načtení vzdáleného repozitáře. Pokud se neobjeví chyby, můžete zkusit poslat projekt na server. Příkaz má podobu</span></p> <p><code><span>git push remote_repo_name branch_name</span></code></p> <p><span>a umožňuje vám posílat na server jakoukoliv vývojovou větev. Avšak pouze poslání větve</span><span> </span><span>“master”</span><span> spustí kopírování souborů do prostoru webu.</span></p> <p> </p> <p><code><span>git push cloudways master </span></code></p> <p> </p> <p><code><span>Total 0 (delta 0), reused 0 (delta 0)</span></code></p> <p><code><span>remote: Ref refs/heads/master received. Deploying master branch to /home/master/applications/d8workshop/public_html...</span></code></p> <p><code><span>remote: Finished.</span></code></p> <p><code><span>To master_dhtpbbmznk@cloudways:/home/master/git_repos/d8workshop.git</span></code></p> <p><code><span> * [new branch]      master -&gt; master</span></code></p> <p> </p> <p><span>Zkontrolujeme to na serveru přes SSH.</span></p> <p><span>Na vzdáleném serveru:</span></p> <p><code><span>cd ~/applications/d8workshop/public_html/</span></code></p> <p><code><span>ls</span></code></p> <p><span>Vidíme, že se zde objevily soubory našeho projektu a také se zde objevily adresáře, zejména adresář web, který by měl být hlavním adresářem webu, tzv. Webroot. Jděte do administrace Cloudways a změňte ho z </span><span><em>public_html</em></span><span> na </span><span><em>public_html/web</em></span><span>. Tuto změna lze udělat až v okamžiku, kdy adresář existuje, proto jsme ji nemohli udělat dříve.</span></p> <p><img alt="" src="https://photos-4.dropbox.com/t/2/AADXphIze7ceIYE9oIHACnUOrnlGK1jjKbmo65UTtOFI1Q/12/83194090/png/2048x1/5/1544554800/0/10/image.png/_/png%2520https%253A%252F%252Fd2mxuefqeaa7sj.cloudfront.net%252Fs_307FD49C2C6A4649BC955C880CC876C12CC1844082F6BC0A281B5652C466F67B_1543789626101_file.png?preserve_transparency=1&amp;size=2048x1&amp;size_mode=5" /></p> <h2><span>Nastavení Drupalu</span></h2> <p><span>Drupal potřebuje znát přístupy k databázi. Jsou různé praxe, kam tyto údaje zadat; nejčastěji to bývá do settings.php v adresáři web/sites/default. V našem případě lektor Radim, který připravil projekt pro workshop, nechal soubor settings.php přenášet přes git bez údajů k databázi a tyto údaje se očekávají v souboru settings.local.php, což je soubor načítaný ze settings.php přes include. Vzor pro tento soubor se také přenesl přes git jako default.settings.local.php, ale my z něj využijeme jen malou část, proto si ho vytvoříme čistý a vložíme do něj pouze přístupy k databázi.</span></p> <p><span>Soubor otevřete v editoru a změňte údaje k databázi</span><span> </span><span>(database,</span><span> username, password) podle údajů z Aplication management v záložce </span><span><em>Access detail.</em></span></p> <p><span>Na vzdáleném serveru:</span></p> <p><code><span>nano web/sites/default/settings.local.php</span></code></p> <p> </p> <p><code><span>&lt;?php</span></code></p> <p><code><span>$databases = array(</span></code></p> <p><code><span>  'default' =&gt;</span></code></p> <p><code><span>    array(</span></code></p> <p><code><span>      'default' =&gt;</span></code></p> <p><code><span>        array(</span></code></p> <p><code><span>          'database' =&gt; 'xxxxxx',</span></code></p> <p><code><span>          'username' =&gt; 'xxxxxx',</span></code></p> <p><code><span>          'password' =&gt; 'supertajneheslo',</span></code></p> <p><code><span>          'host' =&gt; 'localhost',</span></code></p> <p><code><span>          'port' =&gt; </span><span><span>'3306'</span></span><span>,</span></code></p> <p><code><span>          'driver' =&gt; 'mysql',</span></code></p> <p><code><span>          'prefix' =&gt; '',</span></code></p> <p><code><span>        ),</span></code></p> <p><code><span>    ),</span></code></p> <p><code><span>);</span></code></p> <p><span>Uložit, zavřít.</span></p> <p> </p> <h2><span>První instalace - zatím ruční</span></h2> <p><span>První instalaci musíme udělat v příkazové řádce ručně. Jsme stále v adresáři /home/master/applications/d8workshop/public_html (pokud ne, tak se tam vrátíme).</span></p> <p><span>Na vzdáleném serveru:</span></p> <p><code><span>cd /home/master/applications/d8workshop/public_html</span></code></p> <p><code><span>composer install --no-dev</span></code></p> <p><span>Tento příkaz stáhne všechen potřebný software, který Drupal potřebuje. Parametr</span><span> </span><span>—no-dev</span><span> nebude instalovat moduly ze sekce dev, protože na stage či produkčním serveru je většinou nepotřebujeme. Dále nainstalujeme Drupal včetně existující vyexportované konfigurace.</span></p> <p><code><span><span>drush</span></span><span> si minimal --existing-config -y</span></code></p> <p><span>Zbýva změnit heslo pro admina.</span></p> <p><code><span>drush upwd admin mojesupertajnehoslo</span></code></p> <p> </p> <p><span>A je čas se podívat na web. URL najdete v Aplication management v záložce </span><span><em>Access detail</em></span><span> a vypadá nějak takto: </span><span><a href="http://phpstack-cislo-cislo.cloudwaysapps.com/">http://phpstack-cislo-cislo.cloudwaysapps.com/</a></span><span>.</span></p> <p> </p> <p><span>Gratuluji. Máte web na serveru, dokonce nakonfigurovaný. Další změna už bude automatická.</span></p> <p> </p> <h2><span>Doplnění příkazů pro sluhu</span></h2> <p><span><span>Na vzdáleném serveru</span></span><span>:</span></p> <p><code><span>nano ~/git_repos/d8workshop.git/hooks/post-receive</span></code></p> <p><span>a doplňte příkazy pro instalaci změn mezi řádky git a echo:</span></p> <p><code><span>git --git-dir=$GIT_DIR --work-tree=$TARGET checkout ${BRANCH} -f</span></code></p> <p><code><span>cd ${TARGET}</span></code></p> <p><code><span>composer install --no-dev</span></code></p> <p><code><span>cd ${TARGET}/web</span></code></p> <p><code><span>drush cr</span></code></p> <p><code><span>drush entup -y</span></code></p> <p><code><span>drush updb -y</span></code></p> <p><code><span>drush cim -y</span></code></p> <p><code><span>drush cr</span></code></p> <p><code><span>echo "Finished."</span></code></p> <p><span>Poznámka pro experimentátory: Pro zjednodušení tohoto návodu jsem zvolil toto přímočaré řešení. Příkazy od řádky 2 však můžete umístit i do externího scriptu uvnitř repozitáře, čímž získáte možnost měnit tyto příkazy lokálně a posílat je na server společně s ostatními změnami přes Git. Obohaťte čtenáře vaším vylepšeným scriptem v komentáři.</span></p> <h2><span>Přenesení změny na server</span></h2> <p><span>Udělejte</span><span> změnu na lokálním projektu, např. změňte název webu na stránce</span></p> <p><span>/admin/config/system/site-information.</span></p> <p><span>Vyexportujte configuraci.</span></p> <p><code><span>drush cex</span></code></p> <p><span>Označte změněné soubory a zapište změny do místního repozitáře</span><span> </span><span>(commit).</span></p> <p><code><span>git add .</span></code></p> <p><code><span>git commit -m "Update site name"</span></code></p> <p><span>Nakonec změny pošlete na váš Cloudways server.</span></p> <p><code><span>git push cloudways master</span></code></p> <p><span>Sledujte zprávy v consoli a až uvidíte</span><span> </span><span>“Finished”,</span><span> načtěte znovu stránku projektu na serveru. Uvidíte, že všechny změny jsou provedeny a název webu byl přejmenován.</span></p> <p> </p> <p><span>Můžete si pogratulovat. Máte rychlý a bezstarostný deployment změn na server za cenu pod tři stovky.</span></p> <p> </p> <h2><span>Závěr</span></h2> <p><span>Tímto způsobem přenášíte veškeré změny, které jsou obsaženy v kódu, tedy změny vašich custom modulů, vašich témat vzhledu, CSS, stažené contrib moduly, závislosti a veškerou konfiguraci. Pokud potřebujete přenést i nějaký základní obsah, jako například obsah bloků, nebo testovací článek v blogu, použijte modul </span><span><a href="https://www.drupal.org/project/default_content_deploy">Default Content Deploy</a></span><span>, který přenáší obsah do kódu a zpět. Modul obsahuje poměrně podrobnou dokumentaci.</span></p> <h3><span>Výhody</span></h3> <p><span>Toto řešení přesunu změn na server má několik dalších skrytých výhod. Do prostoru webrootu se nenahrává adresář .git, což by bylo bezpečnostní riziko (řada návodů používající opačný princip</span><span> </span><span>“git</span><span> pull” musí adresář .git mazat ručně, nebo to ignoruje). Dále, pokud nechcete, nepotřebujete žádný další repozitář, např. na GitHubu, GitLabu, Bitbucketu apod. a stačí vám pouze jeden pro deployment na serveru.</span></p> <h3><span><span>Problémy</span></span></h3> <p><span>Repozitář Workshop projektu obsahuje </span><span><em>settings.php</em></span><span> a ten se tedy přenáší při změně do adresáře webu. Drupal ale tento soubor blokuje a mění mu atributy tak, aby nešel editovat. Proto bude git při deploymentu vypisovat chybu:</span></p> <p><code><span> error: unable to unlink old 'web/sites/default/settings.php' (Permission denied)</span></code></p> <p><span>Není to zásadní problém, ale počítejte s tím a ve vašich vlastních projektech nechte tento soubor mezi ignorovanými.</span></p> <h3>Prostor pro čtenáře</h3> <p><span>Tento návod shrnuje určitou osobní praxi, která rozhodně nemusí být nejlepší a vyhovující vždy a všem. Např. post-receive hooků pro deployment je celá řada a budu se těšit na vaše návrhy na vylepšení a zkušenosti v komentářích. Také bych byl rád, pokud by se podařilo získat informace o dalších vyhovujících hostingových službách, jako je Cloudways. Nezapomeňte, že bohatství vědomostí Drupal komunity spočívá ve vzájemném sdílení.</span></p> <p> </p> <p><span>Za technické a jazykové korektury tohoto článku děkuji Jakubu Hniličkovi, Radimu Klaškovi a Evě Rázgové.</span></p></div> <div class="field field--name-field-tags field--type-entity-reference field--label-above"> <div class="field__label">Tags</div> <div class="field__items"> <div class="field__item"><a href="/stitky/development" hreflang="cs">development</a></div> </div> </div> <div class="field field--name-field-teaser-image field--type-entity-reference field--label-above"> <div class="field__label">Teaser image</div> <div class="field__item"><a href="/media/11" hreflang="cs">Drupal 8</a></div> </div> Sun, 09 Dec 2018 18:52:13 +0000 martin_klima 371546 at https://www.drupal.cz Na co si dát pozor při alteraci SelectQuery https://www.drupal.cz/clanky/na-co-si-dat-pozor-pri-alteraci-selectquery <span class="field field--name-title field--type-string field--label-hidden">Na co si dát pozor při alteraci SelectQuery</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p>Toto je jen stručný článek pro vývojáře, kteří potřebují v Drupalu 7 či 8 alterovat SQL query. Pokud mu nebudete rozumět, nezoufejte, možná není pro vás.</p> <p>Při práci na alterování SQL query jsem narazil na neočekávané chování některých metod, které ač se zdají být zcela pasivní, mají nečekané důsledky.</p> <p>Hooky pro query alter slouží k tomu, abychom mohli již vytvořený SelectQuery objekt modifikovat, např. joinovat další tabulku, nebo častěji upravit podmínky, které se nacházejí v části za WHERE, a to těsně před tím, než je query provedena a vytvořený SQL dotaz zaslán na MySQL (či jiný) server.</p> <p>Pokud ovšem před modifikací query použijete některou z následujících funkcí</p> <p><span><strong>$query-&gt;__toString()</strong>, např. ve spojení s print($query-&gt;__toString()) pro výpis vzniklého dotazu,</span> nebo<br /><strong><em>$query</em><span>-&gt;</span><span>getArguments</span>()</strong>, pro zjištění, jaké jsou v query argumenty (to jsou ty proměnné označované jako <em>:db_placeholder_x</em>),</p> <p>budete překvapeni nečekanými výsledky. Jakmile totiž funkci <strong><span>getArguments</span></strong><span> použijete v domnění, že vám pouze vrátí argumenty, nevšimnete si, že funkce k vrácení argumentů potřebuje </span>SelectQuery<span> objekt nejprve zkompilovat.</span> Pokud pak provedete požadované změny v SelectQuery objektu, např. změníte podmínku, nemá tato změna efekt, protože query je již zkompilována. Můžete se pak dostat do situace, že kód, který by měl normálně fungovat a vy v něm nevidíte žádnou chybu, prostě nefunguje. S funkcí <span>__toString() je to podobné. </span></p> <p><span>Pro vývojáře je podstatný fakt, že tyto funkce nečekaně mění výsledky kódu, a to i přesto, že podle svých názvů působí zcela pasivně, pouze jako něco, co má získat data či zkonvertovat </span>SelectQuery objekt<span> do řetězce.</span></p> <p>Příklad:</p> <p><code>/**<br /> * Implements hook_query_TAG_alter().<br /> */<br /> function hook_query_TAG_alter(QueryAlterableInterface &amp;$query) {<br />   /** @var \SelectQuery $query */<br />  <br />   // S následují řádkou nebude mít další kód žádný efekt.<br />   <strong>$query_argumants = $query-&gt;getArguments();</strong><br />  <br />   $conditions = &amp;$query-&gt;conditions();<br />   /** @var \DatabaseCondition $condition_field */<br />   $condition_field = &amp;$conditions[0]['field'];<br />   $inner_conditions = &amp;$condition_field-&gt;conditions();<br />  <br />   // Zde si představte konkrétní manipulace s conditions...<br /> }</code></p> <p> </p> <p> </p></div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><a title="Zobrazit profil uživatele." href="/user/martinklima" class="username">martin_klima</a></span> <span class="field field--name-created field--type-created field--label-hidden">Út, 03/20/2018 - 17:48</span> <div class="field field--name-field-tags field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><a href="/stitky/development" hreflang="cs">development</a></div> <div class="field__item"><a href="/stitky/hook" hreflang="cs">hook</a></div> <div class="field__item"><a href="/stitky/query" hreflang="cs">query</a></div> <div class="field__item"><a href="/stitky/pro-vyvojare" hreflang="cs">pro vývojáře</a></div> </div> <section class="field field--name-field-comments-article field--type-comment field--label-above comment-wrapper"> <h2 class="title">Komentáře</h2> <a id="comment-66"></a> <article data-comment-user-id="0" class="comment js-comment by-anonymous"> <mark class="hidden" data-comment-timestamp="1521834342"></mark> <footer class="comment__meta"> <article class="profile"> <div class="field field--name-field-dcz-user-image field--type-image field--label-hidden field__item"> <img src="/sites/default/files/styles/thumbnail/public/default_images/user-placeholder_0.png?itok=R9WfnsOh" width="100" height="100" alt="Drupal user" class="image-style-thumbnail" /> </div> </article> <p class="comment__submitted">Napsal uživatel <span>Miloš (neověřeno)</span> dne Pá, 03/23/2018 - 20:45</p> <span class="permalink"><a href="/comment/66#comment-66" hreflang="cs">Trvalý odkaz</a></span> </footer> <div class="content"> <h3><a href="/comment/66#comment-66" class="permalink" rel="bookmark" hreflang="cs">Workaround?</a></h3> <div class="clearfix text-formatted field field--name-comment-body field--type-text-long field--label-hidden field__item"><p>Děkuju za popis problému. Mohl bys prosím ještě doplnit, jak jsi to vyřešil?</p></div> <drupal-render-placeholder callback="comment.lazy_builders:renderLinks" arguments="0=66&amp;1=default&amp;2=cs&amp;3=" token="ODUVDKWL7SUwtocYzlWzmfQgthBFKGquLIErMmn79g8"></drupal-render-placeholder> </div> </article> <h2 class="title comment-form__title">Přidat komentář</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=416&amp;2=field_comments_article&amp;3=comment_article" token="Epo3O6ala3cLVf74vIwwiLhsrbnQyugA2Pv8eIFlbWA"></drupal-render-placeholder> </section> Tue, 20 Mar 2018 16:48:01 +0000 martin_klima 416 at https://www.drupal.cz Lando - vývojové protředí s Dockerem pro normální lidi https://www.drupal.cz/clanky/lando-vyvojove-protredi-s-dockerem-pro-normalni-lidi <span class="field field--name-title field--type-string field--label-hidden">Lando - vývojové protředí s Dockerem pro normální lidi</span> <div class="clearfix text-formatted field field--name-body field--type-text-with-summary field--label-hidden field__item"><p><strong>Prezentace o rychlém a uživatelsky přívětivém lokálním vývojovém prostředí přednesená na Drupal setkání v Praze 12.3.2018.</strong></p> <p><strong>UPDATE (15.3.2019): </strong>Na tento článek navazuje pokračování s názvem<strong> <a href="https://www.drupal.cz/clanky/lando-kdyz-recept-nestaci"><span>Lando - když recept nestačí</span></a></strong><a href="https://www.drupal.cz/clanky/lando-kdyz-recept-nestaci"><strong> </strong></a></p> <p>Lando je svobodný, open source, cross-platform, vývojové prostředí pro lokální vývoj a vývojářské nástroje postavené na Docker container technologii. Umožňuje i lidem, kteří nejsou specialisté na Docker, využívat všech vymožeností této technologie. Vývojáři nemusí řešit instalace Drushe, Drupal console, Composeru, Gitu a konfiguraci Apache či Nginx serveru a mají vše k dispozici prakticky bez námahy na jedno kliknutí. S Landem přišel splněný sen, kdy můžeme hovořit o rozběhnutí Drupal projektu z prázdného adresáře do stavu prvního administrátorského přihlášení v minutách. A pak už se jen soustředit na práci, která nás baví - prostě vývojářův sen.</p> <p>Vývojáři nazvali Lando jako "<em>The most powerful local dev in the galaxy</em>". Nejsem žádný velký znalec Star Wars, ale mám tušení, že to bude narážka na <strong>Lando Calrissiana</strong>, lidského pašeráka a karetního hráče, který se stal baronem Oblačného města na Bespinu. I když nemohu vědět, jaké všechny local devs se používají v naší galaxii a ani jsem nevyzkoušel všechny, co jsou na Zemi, rozhodně mohu prohlásit, že Lando je to nejlepší vývojové prostředí, jaké jsem kdy zkusil. Zkuste to také a dejte mi vědět v komentářích.</p> <p>PS: Na odkazy ve snímcích nelze klikat, ale všechny je uvádím na konci článku. Prezentaci si také můžete prohlédnout na odkazu: <a href="https://www.dropbox.com/s/pwp0ozzgxjwdz6j/Lando_prezentation.odp">https://www.dropbox.com/s/pwp0ozzgxjwdz6j/Lando_prezentation.odp</a></p> <p> </p></div> <span class="field field--name-uid field--type-entity-reference field--label-hidden"><a title="Zobrazit profil uživatele." href="/user/martinklima" class="username">martin_klima</a></span> <span class="field field--name-created field--type-created field--label-hidden">Út, 03/13/2018 - 11:55</span> <div class="field field--name-field-paragraphs field--type-entity-reference-revisions field--label-hidden field__items"> <div class="field__item"> <div class="paragraph paragraph--type--dcz-para-gallery paragraph--view-mode--default"> <div class="paragraph-content"> <h2 class="field field--name-field-title field--type-string field--label-hidden field__item">Snímky Lando prezentace</h2> <div class="field field--name-field-gallery field--type-image field--label-hidden field__items"> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img0.png" width="800" height="600" alt="Úvodní snímek" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img1.png" width="800" height="600" alt="Proč jsme si v týmu oblíbili Lando?" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img2.png" width="800" height="600" alt="Co a pro koho je Lando?" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img3.png" width="800" height="600" alt="Jak chápu Lando" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img4.png" width="800" height="600" alt="Nový projekt - Jak začít?" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img5.png" width="800" height="600" alt="A namixovat si k tomu služby" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img6.png" width="800" height="600" alt=".lando.yml - příklady" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img7.png" width="800" height="600" alt=".lando.yml - příklady" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img8.png" width="800" height="600" alt="Start" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img9.png" width="800" height="600" alt="Lando - Základní příkazy" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img10.png" width="800" height="600" alt="Užitečné příkazy pro Drupal" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img11.png" width="800" height="600" alt="A další příkazy si můžete nastavit podle potřeby" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/%20lando_prezentation_img12.png" width="948" height="711" alt="Použití .env souboru" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img13.png" width="800" height="600" alt="Ukázka na projektu DCZ" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img14.png" width="800" height="600" alt="Ukázka toolingu pro drush cr" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img15.png" width="800" height="600" alt="Bonus: Co se hodí umět" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img16.png" width="800" height="600" alt="Závěrem: Co se nám líbí" /> </div> <div class="field__item"> <img src="/sites/default/files/2018-03/lando_prezentation_img17.png" width="800" height="600" alt="Zdroje" /> </div> </div> </div> </div> </div> <div class="field__item"> <div class="paragraph paragraph--type--dcz-para-content paragraph--view-mode--default"> <div class="paragraph-content"> <div class="clearfix text-formatted field field--name-field-content field--type-text-long field--label-hidden field__item"><h2>Odkazy</h2> <p>Dokumentace</p> <ul><li><a href="https://docs.devwithlando.io/">https://docs.devwithlando.io/</a></li> </ul><p>GitHub repozitář + Issues</p> <ul><li><a href="https://github.com/lando/lando">https://github.com/lando/lando</a></li> </ul><p>Naše vlastní poznámky (:+1 Jakub Hnilička)</p> <ul><li>PHPstorm + Lando</li> <li>Příklady konfigurace</li> <li><a href="https://github.com/HBFCrew/lando-docs-examples">https://github.com/HBFCrew/lando-docs-examples</a></li> </ul><p> </p></div> </div> </div> </div> </div> <div class="field field--name-field-tags field--type-entity-reference field--label-hidden field__items"> <div class="field__item"><a href="/stitky/development" hreflang="cs">development</a></div> <div class="field__item"><a href="/stitky/lando" hreflang="cs">lando</a></div> </div> <section class="field field--name-field-comments-article field--type-comment field--label-above comment-wrapper"> <h2 class="title comment-form__title">Přidat komentář</h2> <drupal-render-placeholder callback="comment.lazy_builders:renderForm" arguments="0=node&amp;1=391&amp;2=field_comments_article&amp;3=comment_article" token="Ph0A52fnbiiLwOQqy9cMikqodFsfeUW18EO3npA5Xm0"></drupal-render-placeholder> </section> Tue, 13 Mar 2018 10:55:27 +0000 martin_klima 391 at https://www.drupal.cz