Skip to content

Latest commit

 

History

History
528 lines (375 loc) · 21.3 KB

Lando-kdyz_recept_nestaci.md

File metadata and controls

528 lines (375 loc) · 21.3 KB

Lando - když recept nestačí

Tento článek je zaměřen na konfigurovatelnost a rozšiřitelnost Lando receptů. Je určen pro Lando verze RC2 a vyšší. Pokud vám v článku bude něco chybět, nebo chcete-li článek obohatit o kus vašeho receptu, či ho aktualizovat, na konci článku je informace, jak se zapojit.

K čemu je Lando

Lando je multiplatformní open-source nástroj pro vývojáře, který s minimálním úsilím postaví komplexní vývojové prostředí pro lokální vývoj. Toto prostředí je vystavěno na technologii Docker, což má mimo jiné výhodu v tom, že si vývojář nemusí zadělat pracovní počítač velkým množstvím softwaru, přestože na velkém množství softwaru vyvíjí.

Lando umožňuje nastavit pro různé projekty různá prostředí a tato prostředí rychle spustit, snadno ovládat, beze stopy zničit a znovu postavit. K tomu Lando posktytuje jednoduché příkazy a konfigurovatelnost, aby ho mohl používat i začátečník.

Lando je pro ty z nás, kdo chceme:

  • vytvářet různá vývojová prostředí pro různé projekty
  • přenášet konfiguraci vývojového prostředí v týmu přes Git
  • automatizovat opakované, složité instalace a nastavování
  • vyhnout se masochizmu z přímého používání dockeru nebo docker-compose.

Používáme Lando s tímto cílem: „Vývojáři stačí naklonovat git repozitář a spustit lando start. Během pár minut by měl mít vše, co potřebuje pro lokální vývoj.

Nejprve základy - často recept stačí

Začněme tím, že nechceme nic speciálního vymýšlet. Potřebujeme si jen “upéct” prostředí, které pro nás už někdo připravil ve formě receptu. Takových receptů je celá řada, např.

Dejme tomu, že máme chuť vyzkoušet si Drupal 8. Je to jednoduché. Založte si adresář (v mé ukázce je to my_drupal8). Nemusíme podle receptu sami vařit, stačí Landu ukázat, podle jakého výše uvedeného receptu má vařit a dodat pár údajů.

marty@ProBook ~ $ mkdir my_drupal8
marty@ProBook ~ $ cd my_drupal8/
marty@ProBook ~/my_drupal8 $ lando init
? From where should we get your app's codebase? current working directory
? What recipe do you want to use? drupal8
? Where is your webroot relative to the init destination? web
? What do you want to call this app? my-drupal8-web

NOW WE'RE COOKING WITH FIRE!!!
Your app has been initialized!

Go to the directory where your app was initialized and run `lando start` to get rolling.
Check the LOCATION printed below if you are unsure where to go.

Oh... and here are some vitals:

 NAME      my-drupal8-web                                      
 LOCATION  /home/marty/my_drupal8                              
 RECIPE    drupal8                                             
 DOCS      https://docs.devwithlando.io/tutorials/drupal8.html

Recept zajistil, že máme kromě prostředí i užitečné příkazy.

$ lando
Usage: lando <command> \[args\] [options]

Commands:
  lando composer          Runs composer commands
  lando config            Displays the lando configuration
  lando db-export [file]  Exports database from a database service to a file
  lando db-import <file>  Imports a dump file into a database service
  lando destroy           Destroys your app
  lando drupal            Runs drupal console commands
  lando drush             Runs drush commands
  lando info              Prints info about your app
  lando init              Initializes code for use with lando
  lando list              Lists all running lando apps and containers
  lando logs              Displays logs for your app
  lando mysql             Drops into a MySQL shell on a database service
  lando php               Runs php commands
  lando poweroff          Spins down all lando related containers
  lando rebuild           Rebuilds your app from scratch, preserving data
  lando restart           Restarts your app
  lando share             Shares your local site publicly
  
  lando ssh               Drops into a shell on a service, runs commands
  lando start             Starts your app
  lando stop              Stops your app
  lando version           Displays the lando version

Options:
  --clear        Clears the lando tasks cache                       [boolean]
  --lando        Show help for lando-based options                  [boolean]
  --verbose, -v  Runs with extra verbosity                            [count]
  --version      Show version number                                [boolean]

Aby se upečené prostředí také spustilo, nesmíme zapomenout na

lando start

a je hotovo. Máme Composer, Drush, Drupal consoli.

Když chceme víc - tuníme recept

Dejme tomu, že potřebujeme upéct něco jinak a nebo něco navíc. Máme tyto možnosti:

  • přizpůsobit si poskytnutý recept - config
  • přidávat a konfigurovat další služby (něco jako přílohy a mrkvový salát) - services
  • definovat příkazy a zjednodušující nástroje (jako brčko nebo vidličku) - tooling
  • definovat akce pro jednotlivé fáze - events
  • automatizovat opakované příkazy a nastavení do instalačních kroků - build
  • definovat vlastní služby na nižší úrovni docker-compose (něco jako vypěstovat si vlastní mrkev)

V následujících příkladech vyjdeme z existujícího konfiguračního souboru .lando.yml, který ve své základní podobě vypadá takto:

name: my-drupal8-web
recipe: drupal8
config:
  webroot: web

Důležité je pochopit, že vše, co se vztahuje ke konfiguraci receptu, a tudíž to musí recept podporovat, se nachází pod klíčem “config”.

Případ 1: Potřebujeme specifickou verzi PHP

V základní verzi máme v tuto chvíli nainstalováno PHP v 7.2.14, MySQL 5,7 a webserver Apache/2.4.25 (Debian). Dejme tomu, že na produkci máme verzi 7.0, nebo 7.1, tak ji chceme mít i lokálně. Na to, jaké verze (resp. docker image) jsou podporované, najdete vždy v dokumentaci.

name: my-drupal8-web
recipe: drupal8
config:
  webroot: web
  php: "7.0"

Verze 7.0 je v uvozovkách, protože YAML by to bez uvozovek přeložil jako 7 a Lando by se nespustilo. Pro verzi 7.1 to můžete nechat bez uvozovek. Aktualizace: V novějších verzích by to už mělo být opraveno a uvozovky nejsou nutné.

Stejně tak je možné konfigurovat i další věci, např. verzi MySQL,

  database: mysql:8.0

nebo typ webserveru, tedy Nginx místo Apache.

  php: "7.2"
  via: nginx  

Případ 2: Potřebujeme Drush 9 a Xdebug

Nyní si nastavíme, že chceme místo Drush 8 novější Drush 9 a zapnout podporu pro Xdebug.

name: my-drupal8-web
recipe: drupal8
config:
  webroot: web
  php: "7.0"
  drush: 9
  xdebug: true

Pozor! Po každé změně konfigurace musíte prostředí znovu postavit (nebo upéct) příkazem

  lando rebuild

což je novinka od verze RC2.

Kontrola verze Drushe:

  lando drush version
    Drush version : 9.5.2

Pokud chcete mít Drush součástí vašeho projektu, máte ho součástí composer.json. V takovém případě bude Lando používat Drush definovaný ve vašem projektu a verzi v .lando.yml bude ignorovat.

Případ 3: Preferujeme MariaDB nebo Postgres místo MySQL

name: my-drupal8-web
recipe: drupal8
config:
  webroot: web
  php: "7.0"
  drush: 9
  xdebug: true
  database: mariadb

Kontrola:

lando mysql -v
  Server version: 10.1.38-MariaDB Source distribution

Můžete požadovat i Postgres, např.

config:
  database: postgres:9.6

Případ 4: Potřebujeme extra konfiguraci pro PHP nebo MySQL

Někdy si potřebujeme nastavit něco speciálního v php.ini nebo v my.cnf. Tu vychytávku, která se má nastavit, dáme do samostatného souboru a řekneme Landu, kde ho najde. V ukázce jsou soubory v adresáři config (adresář config je ve stejném adresáři jako .lando.yml)

name: my-drupal8-web
recipe: drupal8
config:
  webroot: web
  php: "7.0"
  drush: 9
  xdebug: true
  database: mariadb
  config:
    php: config/my-custom-php.ini
    database: config/my-custom.cnf

Taková malá, ne zcela praktická ukázka, co by mohlo být v my-custom-php.ini

max_execution_time = 180
date.timezone = Europe/Prague
memory_limit = 256M
post_max_size = 99M

Nezapomeneme na

lando rebuild -y

Případ 5: Potřebujeme zachytávat maily

Při vývoji je užitečné zachycovat e-maily v lokálním prostředí, neriskovat že nám nějaký mail odeslaný zákazníkovi cronem unikne do internetu. K tomu slouží různé služby a Lando nabízí Maihog a my si tuto službu přidáme k ostatním. Zatím jsme konfigurovali recept. Nyní přidáváme další službu, resp. další Docker container. Služby jsou definovány pod klíčem “services”. Pojmenovat si je můžete libovolně, takže místo “mailhog:” můžete mít třeba “mailserver:”.

services:
  mailhog:
    type: mailhog
    hogfrom:
      - appserver      

Nyní všechny maily z PHP skončí ve falešné mailové schránce Mailhogu, kterou navštívíme přes webové rozhraní. Můžete snadno otestovat.

 lando php -r "mail('[email protected]', 'subject', 'message');"

Adresa na webové rozhraní Mailhogu se objevila po dokončení příkazu:

lando start

nebo ji najdeme přes lando info, nebo ještě lépe s definicí služby, která nás zajímá:

lando info -s mailhog

Případ 6: Je libo PhpMyAdmin?

services:
  pma:
    type: phpmyadmin
    hosts:
      - database

Případ 7: Node+SASS atd.

services:
  node:
    type: node:10
    globals:
      gulp-cli: "latest"
      gulp: "latest"

Případ 8: Potřebujeme kompilovat Compass SASS na CSS.

Někdy máme projekt, který nepoužívá Grunt ani Gulp a cílem je konvertovat SASS na CSS. Pak se může hodit tato odlehčená verze. Posilujeme naši odvahu a použijeme “build”, kam uložíme všechny kroky, které se mají vykonat při vytváření této služby.

services:
  compass:
    type: ruby
    build: gem update --system && gem install sass compass bootstrap-sass breakpoint

Případ 9: Potřebujeme Solr server

services:
  solr:
    type: solr:6.6
    core: my_core
    portforward: 8983
    overrides:
      environment:
        HTTPS_METHOD: redirect
    config:
      dir: config/solr

Případ 10: Chceme mít kód podle standardů - PHP Code sniffer - phpcs

V tompo případě si ukážeme dvě nové věci. Za prvé vytvoříme vlastní novou službu z vybraného existujícího image, který se nachází na Docker hubu (doposud jsme používali jen ty doporučené v Landu). Službu pojmenujeme “phpcs” a dáme ji typ “compose”. Command “tail -f /dev/null” nikdy neskončí a udržuje tím container v chodu a naši službu aktivní.

services:
  phpcs:
    type: compose
    services:
      image: willhallonline/drupal-phpcs:alpine
      command: tail -f /dev/null

Za druhé si ukážeme tooling, což je způsob, jak definovat vlastní příkazy. Zde definujeme příkaz “phpcs”, předáváme ho i s jeho parametry službě phpcs a spustíme ho tam jako uživatel root.

tooling:
  phpcs:
    service: phpcs
    user: root    

Pro kontrolu PHP kódu pak stačí jen zavolat:

lando phpcs cesta_k_souboru_či_adresáři

Případ 11: Potřebujeme programátorský editor (IDE) bez instalace

Není to příliš běžné, že by vývojář neměl nainstalovaný editor, ale např. při školení se to stát může. V takovém případě stačí přidat následující službu, která promění internetový prohlížeč na portu 8081 v profesionální editor pro programátory. Port si můžeme samozřejmě změnit.

services:
  ide:
    type: compose
    services:
      image: martinklima/cloud9-with-codeintel:1.0
      ports:
       - '8081:80'
      command: "node /cloud9/server.js -p 80 -l 0.0.0.0 -w /app -a :"

Případ 12: Chci mít zachovanou historii příkazů v kontejneru

Po restartu Landa, resp. po novém startu docker kontejneru zmizí historie příkazů, které po připojení přes lando ssh do kontejneru zapíšete. Následující trik namapuje historii do souboru .appserver_bash_history.txt v adresáři projektu.

services:
  appserver:
    overrides:
      volumes:
        - .appserver_bash_history.txt:/var/www/.bash_history
      environment:
        PROMPT_COMMAND: "history -a"

Problém tohoto triku spočívá v tom, že je nutné, aby soubor .appserver_bash_history.txt existoval v hostitelském systému dříve, než spustíte Lando start nebo rebuild, jinak se vám vytvoří adresář s tímto názvem a nefunguje to.

Zde je vylepšená verze, která funguje automaticky. Spočívá v tom, že se soubor s historií přesune do nového adresáře a ten se mapuje jako volume.

services:
  appserver:
    overrides:
      environment:
        PROMPT_COMMAND: "history -a"
        HISTFILE: /var/www/.history/hist.txt
      volumes:
        - ${PWD}/.history:/var/www/.history                                               

Případ 13: Chci rychle zapínat a vypínat Xdebug

Mít trvale zapnutý Xdebug znamená mít trvale pomalejší PHP. Proto je dobré si ho zapnout, jen když je to potřeba. Zdroj tohoto nápadu je zde: lando/lando#1668 (comment)

Pro nginx:

tooling:
  xdebug-on:
    service: appserver
    description: Enable xdebug for nginx.
    cmd: docker-php-ext-enable xdebug && pkill -o -USR2 php-fpm
    user: root
  xdebug-off:
    service: appserver
    description: Disable xdebug for nginx.
    cmd: rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && pkill -o -USR2 php-fpm
    user: root

Pro Apache:

tooling:
  xdebug-on:
    service: appserver
    description: Enable xdebug for apache.
    cmd: "docker-php-ext-enable xdebug && /etc/init.d/apache2 reload"
    user: root
  xdebug-off:
    service: appserver
    description: Disable xdebug for apache.
    cmd: "rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && /etc/init.d/apache2 reload"
    user: root

Případ 14: Potřebuji z PHP komunikovat s Microsoft SQL serverem

PHP standardně neobsahuje rozšíření pro MS SQL server. Zde je postup, jak nainstalovat PHP extensions pdo_sqlsrv a sqlsrv do PHP 7.2.

services:
  appserver:
    type: php:7.2
    overrides:
      environment:
        ACCEPT_EULA: "Y"
    build_as_root:
      - apt-get update -y
      - apt-get install apt-transport-https -y
      - curl https://packages.microsoft.com/keys/microsoft.asc | apt-key add -
      - curl https://packages.microsoft.com/config/ubuntu/16.04/prod.list > /etc/apt/sources.list.d/mssql-release.list
      - apt-get update -y
      - apt-get install msodbcsql17 -y
      - apt-get install unixodbc-dev -y
      - pecl install sqlsrv
      - pecl install pdo_sqlsrv
      - docker-php-ext-enable sqlsrv
      - docker-php-ext-enable pdo_sqlsrv

Případ 15: Chci používat své oblíbené bash aliasy i v kontejneru appserveru

Část vývojářů posílá do služby appserver příkazy přes příkaz lando, jako např. lando drush status. Já patřím mezi tu skupinu, která si na začátku práce otevře terminál a příkazem lando ssh, případně lando ssh -s <název služby> si otevře příkazový řádek přímo v konkrétní službě a píše příkazy tam jako např. drush status. Je to pro mě pohodlnější a rychlejší.

K dobré efektivitě patří zažité zkratky prostřednictvím aliasů, které je otravné nastavovat znovu a znovu po každém rebuildu služby. Zde je návod, jak to udělat, aby si kontejner služby načetl připravený soubor s definicemi aliasů.

services:
  appserver:
    build:
      # Load custom alias definitions from .lando/aliases/.bash_aliases file.
     - /bin/sh -c "echo 'if [ -f /app/.lando/aliases/.bash_aliases ]; then . /app/.lando/aliases/.bash_aliases; fi' > ~/.bashrc"

Vychytávka vytvoří soubor .bashrc, který se po vytvoření kontejneru služby automaticky spustí. Ten obsahuje test, zda existuje soubor s aliasy (v našem případě .lando/aliases/.bash_aliases) a pokud ano, pak něj spustí, a tím nahraje do systému požadované aliasy.

Pokud se rozhodnete soubor s aliasy během práce aktualizovat, stačí upravit váš soubor s aliasy a aktualizovat systém v kontejneru pomocí příkazu source ~/.bashrc nebo přes Lando jako lando source ~/.bashrc a je to.

Případ 16: Potřebuji v týmu používat více ini souborů s nastavením pro PHP

Lando standardně podporuje pouze jeden konfigurační soubor pro PHP. Pokud potřebujete mít jeden config týmový a zároveň umožnit vývojářům, aby mohli používat vlastní, např. pro zapnutí Xdebug profileru, použijte následující vychytávku.

services:
  appserver:
    overrides:
      environment:
        # Load custom php.ini files if exist in .lando/config/php directory.
        PHP_INI_SCAN_DIR: "/usr/local/etc/php/conf.d:/app/.lando/config/php"

Případ 17: Potřebuji aktivovat Xdebug profiler

Do configu pro PHP přidejte následující řádky:

xdebug.profiler_enable=1
xdebug.profiler_output_dir=/app/profiler

nebo mějte připravený soubor profiler.ini a umístěte ho do adresáře s PHP configy, viz případ 16.

Nezapomeňte, že adresář pro profiler output musí existovat, takže je třeba ho předem vytvořit.

Restartujte Xdebug, ideálně podle návodu v případu 13, tedy

lando xdebug-off; lando xdebug-on

Profiler bude nyní pro každé spuštění PHP generovat soubory, které lze pak načíst ve vizualizačních nástrojích, např. PSPstorm nebo KCacheGrind.

Připad 18: Změnila se mi IP adresa a přestal mi fungovat Xdebug a spojení s Hostem

Vemi tento nepříjemný problém se stává pokud vývojář přejde z domova do kanceláře, nebo vytáhne ethernetový kabel a přejde z drátového internetu na bezdrátový. Hostitelskému počítači (počítač, kde se spouští Lando) se změní IP adresa a lecos přestane pracovat, především to, co je na IP adresu navázáno, jako např. Xdebug remote host, nebo spojení na SSH tunel. Řeší to následují příkaz:

export LANDO_HOST_IP=<newIP>; export XDEBUG_CONFIG="remote_enable=true remote_host=<newIP>"

Aby to bylo opravdu pohodlné, lze použít funkci, která se definuje stejně jako alias, s výhodou, že umí použít parametry.

function changeip() { export LANDO_HOST_IP=$1; export XDEBUG_CONFIG="remote_enable=true remote_host=$1"; }

Není pak nic jednoduššího, než se podívat, jaká je aktuální IP adresa hostitelského počítače a zadat např. příkaz:

lando changeip 10.0.0.1

Aby fungovaly i další Drupal nastavení automaticky, použijeme místo konkrétní IP adresy načtení hodnoty z env proměnné LANDO_HOST_IP. Jako příklad použijeme připojení dalších databází do Drupalu v settings.php.

// Credential for data migration source from MS SQL server.
$conf['mssql_source_connection'] = [
  'database' => 'mssql_db',
  'username' => 'sa',
  'password' => 'supersecretpassword',
  'servername' => getenv('LANDO_HOST_IP'),
  'character_set' => "UTF-8",
];

// Credential for data migration source from MySQL server.
$databases['source_database']['default'] = array(
  'driver' => 'mysql',
  'database' => 'old_db',
  'username' => 'user',
  'password' => 'password',
  'host' => getenv('LANDO_HOST_IP'),
  'port' => '3366',
  'collation' => 'utf8_general_ci',
);

Předzávěr

A kdyby toto vše, co je přednastaveno v receptech a v základních konfiguracích někomu nestačilo, vždy je možné jít o úroveň níže, vytvořit vlastní docker-compose.yml a předat ho Landu. Zájemce o více informací odkazuji na dokumentaci.

Závěr

Tento článek obsahuje moji přednášku z Drupal setkání navazujícího na Drupal trénink v únoru roku 2019. Je volným pokračováním o rok starší přednášky a článku Lando - vývojové protředí s Dockerem pro normální lidi. Reflektuje rozsáhlé změny mezi verzemi RC1 a RC2 a tedy oproti staršímu článku odpovídá realitě prvního čtvrtletí roku 2019.