Motivace

Vývojář projektů na Drupalu 8 si vždy časem musí položit klasické otázky “Kam s tím?”, “Jak to tam dostat?” a “Jak to tam snadno aktualizovat?”. 

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í.

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.

Klasická cesta je trnitá

Drupal 8 obsahuje po základní instalaci přes 27 tisíc souborů. Klasická cesta - zkopírovat tento balík na hosting přes SFTP nebo zastaralé FTP - 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 (text 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á se změnila, 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... 

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.

Cesta profesionálů

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 podporoval to, co má na počítači každý člen profesionálního týmu:

  • SSH přístup
  • Composer
  • Drush
  • Git

Pokud váš hosting tyto parametry má, můžete tuto kapitolu přeskočit. Většina levných hostingů, kde nejste tzv. root (superuživatel se všemi právy a zodpovědností), tyto požadaky nesplňuje. Např. Český hosting má na VMS (Virtual 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ě.

Cloudways

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.

Cloudways - Faster Drupal Hosting (stránka věnovaná hostingu pro Drupal)

Cloudways - hlavní stránka

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 “PHP 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. 

Pozn.: 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.

Pár důležitých míst v administraci:

Server management

V záložce Master credentials si nahrajte SSH klíč 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 https://help.github.com/articles/connecting-to-github-with-ssh. 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.

Aplication management

V záložce Access detail máte přidělenou testovací URL adresu pro váš web a můžete si nastavit heslo k databázi.

V záložce Application Settings si nastavte položku Folder na název projektu (d8workshop). Je to název adresáře a pomůže vám to v orientaci. Soubory projektu pak snadno najdete v adresáři ~/applications/d8workshop/public_html. Tuto cestu budete potřebovat znát.

Jakmile máte vytvořený hosting pro váš projekt, můžeme se konečně dostat k návodu na deployment.

 

Deployment - potřebné znalosti a dovednosti

Tento článek předpokládá, že toto máte a znáte:

  • 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á.
  • Základní práci s Composerem - ten nám bude nahrávat Drupal, moduly a závislosti.
  • Drush - budu používat Drush příkazy, protože je to jednodušší a protože jsme přece profíci, ne?
  • Prostředí příkazové řádky - budete na serveru pracovat vzdáleně, takže abyste chápali, co děláte (cd, ls, mkdir apod...)
  • SSH klíč - předpokládám, že máte SSH klíč, jehož veřejnou část jste nahráli na server.
  • 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 https://github.com/Drupalcz/workshop 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.
  • Máte na svém počítači rozběhnutý projekt z výše uvedeného bodu.

Jak na to

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.

SSH připojení

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 .ssh/config a vložte do něj

Host cloudways

    Hostname ip_vašeho_serveru

    User master_login_username

Název serveru si vymyslete podle potřeby, já jsem použil “cloudways”. Uživatelské jméno a IP adresu  najdete v záložce Server management - Master credentials. Uložte a pak napište do terminálu:

ssh cloudways

...a měli byste tam být.

Vzdálený git repozitář

Nyní vytvoříme vzdálený git repozitář v adresáři git_repos. 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 d8workshop.git. Tento repozitář bude přijímat naše změny jako pomyslný “další člen našeho týmu”. Na vzdáleném serveru:

mkdir git_repos

cd git_repos

mkdir d8workshop.git

cd d8workshop.git

git init --bare

Posledním příkazem jsme vytvořili strukturu prázdného git repozitáře a měli bychom vidět zprávu:

Initialized empty Git repository in /home/master/git_repos/d8workshop.git/

 

Vytvoření sluhy

Vytvoříme si v adresáři hooks 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í (hostingem) je ~/applications/d8workshop/public_html.

 

Vytvoření nového souboru post-receive. Na vzdáleném serveru:

cd hooks

nano post-receive

 

Do otevřeného editoru vložte:

#!/bin/bash

GIT_DIR="/home/master/git_repos/d8workshop.git"

TARGET="/home/master/applications/d8workshop/public_html"

BRANCH="master"

 

while read oldrev newrev ref

do

        # only checking out the specified branch you would like to deploy

        if [[ $ref = refs/heads/$BRANCH ]];

        then

                echo "Ref $ref received. Deploying ${BRANCH} branch to ${TARGET}..."

                git --git-dir=$GIT_DIR --work-tree=$TARGET checkout ${BRANCH} -f

                # You will place more commands HERE...

                echo "Finished."

        else

                echo "Ref $ref received. Only the ${BRANCH} branch may be deployed on this server."

        fi

done

Uložte a zavřete (Ctrl+O, Enter, Ctrl-X). Náš sluha čeká, zda byla přijata změna ve větvi (branch) “master”. Pokud ano, vykopíruje všechny soubory do adresáře TARGET a pomocí parametru -f 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.

chmod +x post-receive

Propojení projektu se vzdáleným repozitářem

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 “.git”. 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ý.

git remote add cloudways master_xxx@cloudways:/home/master/git_repos/d8workshop.git

První výskyt slova “cloudways” je název vzdáleného repozitáře. Můžete si tam dát co chcete, třeba i “sluha”. Slovo master_xxx@cloudways” znamená, že se připojujete jako uživatel master_xxx na server cloudways, což je označení serveru, který jste definovali v souboru .ssh/config. Text “/home/master/git_repos/d8workshop.git” je cesta k repozitáři na vzdáleném serveru. Příkaz “git 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:

git remote show cloudways

 

* remote cloudways

  Fetch URL: master_dhtpbbmznk@cloudways:/home/master/git_repos/d8workshop.git

  Push  URL: master_dhtpbbmznk@cloudways:/home/master/git_repos/d8workshop.git

  HEAD branch: (unknown)

 

pro načtení vzdáleného repozitáře. Pokud se neobjeví chyby, můžete zkusit poslat projekt na server. Příkaz má podobu

git push remote_repo_name branch_name

a umožňuje vám posílat na server jakoukoliv vývojovou větev. Avšak pouze poslání větve “master” spustí kopírování souborů do prostoru webu.

 

git push cloudways master 

 

Total 0 (delta 0), reused 0 (delta 0)

remote: Ref refs/heads/master received. Deploying master branch to /home/master/applications/d8workshop/public_html...

remote: Finished.

To master_dhtpbbmznk@cloudways:/home/master/git_repos/d8workshop.git

 * [new branch]      master -> master

 

Zkontrolujeme to na serveru přes SSH.

Na vzdáleném serveru:

cd ~/applications/d8workshop/public_html/

ls

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 public_html na public_html/web. Tuto změna lze udělat až v okamžiku, kdy adresář existuje, proto jsme ji nemohli udělat dříve.

Nastavení Drupalu

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.

Soubor otevřete v editoru a změňte údaje k databázi (database, username, password) podle údajů z Aplication management v záložce Access detail.

Na vzdáleném serveru:

nano web/sites/default/settings.local.php

 

<?php

$databases = array(

  'default' =>

    array(

      'default' =>

        array(

          'database' => 'xxxxxx',

          'username' => 'xxxxxx',

          'password' => 'supertajneheslo',

          'host' => 'localhost',

          'port' => '3306',

          'driver' => 'mysql',

          'prefix' => '',

        ),

    ),

);

Uložit, zavřít.

 

První instalace - zatím ruční

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).

Na vzdáleném serveru:

cd /home/master/applications/d8workshop/public_html

composer install --no-dev

Tento příkaz stáhne všechen potřebný software, který Drupal potřebuje. Parametr —no-dev 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.

drush si minimal --existing-config -y

Zbýva změnit heslo pro admina.

drush upwd admin mojesupertajnehoslo

 

A je čas se podívat na web. URL najdete v Aplication management v záložce Access detail a vypadá nějak takto: http://phpstack-cislo-cislo.cloudwaysapps.com/.

 

Gratuluji. Máte web na serveru, dokonce nakonfigurovaný. Další změna už bude automatická.

 

Doplnění příkazů pro sluhu

Na vzdáleném serveru:

nano ~/git_repos/d8workshop.git/hooks/post-receive

a doplňte příkazy pro instalaci změn mezi řádky git a echo:

git --git-dir=$GIT_DIR --work-tree=$TARGET checkout ${BRANCH} -f

cd ${TARGET}

composer install --no-dev

cd ${TARGET}/web

drush cr

drush entup -y

drush updb -y

drush cim -y

drush cr

echo "Finished."

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.

Přenesení změny na server

Udělejte změnu na lokálním projektu, např. změňte název webu na stránce

/admin/config/system/site-information.

Vyexportujte configuraci.

drush cex

Označte změněné soubory a zapište změny do místního repozitáře (commit).

git add .

git commit -m "Update site name"

Nakonec změny pošlete na váš Cloudways server.

git push cloudways master

Sledujte zprávy v consoli a až uvidíte “Finished”, 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.

 

Můžete si pogratulovat. Máte rychlý a bezstarostný deployment změn na server za cenu pod tři stovky.

 

Závěr

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 Default Content Deploy, který přenáší obsah do kódu a zpět. Modul obsahuje poměrně podrobnou dokumentaci.

Výhody

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 “git 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.

Problémy

Repozitář Workshop projektu obsahuje settings.php 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:

 error: unable to unlink old 'web/sites/default/settings.php' (Permission denied)

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.

Prostor pro čtenáře

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í.

 

Za technické a jazykové korektury tohoto článku děkuji Jakubu Hniličkovi, Radimu Klaškovi a Evě Rázgové.