Z WAMPu do Dockeru, jednoduše

Motivace

Vždy když přijímáme nového vývojáře do ExitShopu tak největší peklo je, rozjet si systém lokálně, typicky na nějakém tom WAMPu (Xampp, Neard….). Obvykle to zahrnuje tři kroky:

  1. Naklonovat si repozitář
  2. Donahrát neverzované soubory (configy a nějaká defaultní uživatelská data – obrázky atd)
  3. Naimportovat databáze

Mezitím se může pokazit asi tak sto věcí:

  1. Vývojář nebude mít požadovanou PHP extension,
  2. bude mít jinou verzi PHP než je na produkci,
  3. bude mít špatně nakonfigurované PHP
  4. (body 1-3 platí navíc zvlášť i pro každou součást vašeho stacku)
  5. nebude umět (nebo být ochoten) si nastavovat virtual hosty
  6. nebude umět (nebo být ochoten) nastavovat si lokální SSL certifikát
  7. nebude umět (nebo být ochoten) si nainstalovat další služby typu Redis, memcached, fake smtp server, …

Řešení – sjednocení vývojového prostředí

Tedy co se operačního systému a služeb týče. Vyvíjet můžete samozřejmě dál ve svých oblíbených programech. Docker už nějakou dobu běží bez problému i pod Windows takže ani ve vašem OS nebude problém.

Příklad z praxe – převední PHP a MySQL aplikace z WAMPu do Dockeru

Představte si, že máte aplikaci běžící pod nějakou konkrétní verzí PHP, například 8. K tomu budete chtít Apache a MariaDB a celé to poběží na Debianu.

Nejprve si nainstalujeme Docker Desktop.

Vezmeme zdrojáky z WAMPu a nakopírujeme si je jinam, třeba do C:\Docker\mojeappka

WAMP můžeme vypnout ale v systému si ho určitě nechte. Nemusíte hned každou aplikaci Dockerizovat a tyto dva systémy mohou v pohodě existovat vedle sebe.

Dockerfile

Je to hlavní soubor, dáme si ho do rootu aplikace, budeme jej verzovat ale na produkci jej nahrávat nebudeme :)

Rovnou sem dám příklad. Na prvním řádku definujeme, z jaké image chceme vycházet. Vybral jsem tuhle, která kombinuje Debian Buster, Apache a PHP verzi 8.0.3.

FROM php:8.0.3-apache-buster

# nakopírování apache vhosts
COPY docker-konfigurace/000-default.conf /etc/apache2/sites-available/000-default.conf

# nakopírování našich změn pro php.ini
COPY docker-konfigurace/my-php.ini /usr/local/etc/php/conf.d/my-php.ini

# update
RUN apt-get update

# doinstalujeme PHP extension
RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli

# příklad instalace programu z deb balíčku
RUN apt-get install -y wget
RUN wget https://github.com/wkhtmltopdf/packaging/releases/download/0.12.6-1/wkhtmltox_0.12.6-1.buster_amd64.deb
RUN apt install -y ./wkhtmltox_0.12.6-1.buster_amd64.deb

# povolení apache modulů
RUN a2enmod rewrite

Následuje nakopírování virtual hostů. Příklad takového souboru níže. Všimněte si té cesty. I když jsme na Windows, tak definujeme cesty na zvoleném OS (Debianu).

<VirtualHost *:80>
    DocumentRoot "/var/www/html"
    ServerName mojeappka.test
    ServerAlias www.mojeappka.test

    <Directory "/var/www/html">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride all
    </Directory>
</VirtualHost>

Následuje nakopírování změn oproti defaultnímu php.ini souboru. Může to být třeba vyšší memory limit atd.

Pak spustíme update, abychom při instalaci balíčků měli nové verze. Balíčku můžeme instalovat tak, jak jsme z Linuxu zvyklí – z repozitářů nebo z .deb balíčků. PHP extensions můžeme šikovně instalovat přes docker-php-ext-install XX.

To bychom měli Dockerfile, který definuje náš kontejner.

docker-compose.yml

Tento soubor nám dovolí nakombinovat více služeb do jednoho celku. Dáme si ho do rootu aplikace, budeme jej verzovat ale na produkci jej opět nahrávat nebudeme :)

version: '3.8'

services:
  web:
    image: php:8.0.3-apache-buster
    ports:
      - '80:80'
    volumes:
      - .:/var/www/html/
    build: .
    links:
      - db
    extra_hosts:
      - "mojeappka.test:127.0.0.1"
    hostname: mojeappka.test

  db:
    image: mariadb:10.3.23
    restart: 'always'
    ports:
      - "3306:3306"
    volumes:
      - ./docker-konfigurace/databases:/docker-entrypoint-initdb.d
    environment:
      MYSQL_ROOT_PASSWORD: heslo

  adminer:
    image: adminer
    restart: always
    ports:
      - 8080:8080

Na příkladu vidíme 3 služby. Prvním je webový server, který jsme prakticky konfigurovali výše. Nastavíme mu porty, na kterých má běžet, hostname a a volume – čili kde se má v tom Debianu připojit náš projekt.

Další službou je databáze – zvolíme image, nastavíme porty, v sekci volumes můžeme určit cestu k adresáři (docker-konfigurace/databases), kde máme strukturu DB v SQL souborech – tím se nám při prvotním zbuildování kontejneru nahraje DB. A taky root heslo k db.

Všimněte si další služby – Adminer. Bude běžet na portu 8080, čili localhost:8080. Tak jednoduché je přidávat si další služby.

Jdeme na to

Máme to nachystané. Spustíme tenhle příkaz. Stáhnou se images, provede se jejich instalace a spustí se příkazy v našem Dockerfile – instalace balíčků atd.

docker-compose build

A teď to celé spustíme:

docker-compose up

A mělo by to jet :)

  • na http://localhost/ (případně mojeappka.test, pokud si nastavíte v systému hosts file) běží web
  • na http://localhost:8080/ běží Adminer – do DB se připojíme na hostname “host.docker.internal”, uživatel “root”, heslo “heslo”

Spouštět kontejnry můžete i z GUI Docker Desktopu:

Vyplatí se to všechno?

Ano, pro větší aplikace, na kterých deláte denně, v týmu nebo která má nějaké specifičnější nároky na konfiguraci nebo služby, tak to určije ano.

Nemusíte ale hned vše dockerovat. Rychlejší je samozřejmě hodit si aplikaci do WAMPu (aktuálně používám Neard, protože se nemusí instalovat a má hezké rozhraní pro tvorbu vhostů, ssl a další vychytávky) a ona tak nějak běží ihned.

Upgrade CodeIgniteru z verze 2 na 3 – na co si dát pozor?

Dokumentace CodeIgniteru celkem detailně popisuje postup upgradu na této stránce. Kromě inkrementálních upgradů je tam delší článek o upgradu verze 2.2.x na 3.0.x. Vypíchnu sem jen několik věcí, se kterými jsem měl konkrétní problémy:

  • Metody třídy Input, Session a Config v případě neodeslání hodnoty/nenalezení nevrací FALSE jako ve verzi 2, ale nově NULL – dává to větší smysl, ale může být problém, pokud porovnáváte typově a v celém projektu se to dost špatně hledá, je to velká změna.
  • Třídy musí začínat velkým písmenem – může být problém, pokud pracujete na Windows. Git totiž rozlišuje velikosti písmen.
  • Sessions už se neukládají do cookies. Můžete si vybrat, jaký session driver použijete. Nejjednodušší je souborový systém a databáze, my z výkonnostních důvodů použili memcached.
  • V databázovém configu se změnilo dost věcí, ale jedna věc je zásadní – musíte vypnout ‘pconnect’ – persistent connection.
  • Z pravidel třídy Form_validation mizí ‘xss_clean’. XSS by se mělo aplikovat na output, takže ho z validace odstranili.
  • Položka ‘base_url’ v configu nemůže být prázdná. Pokud ji nemůžete nastavit v configu, můžete ji změnit i později v kódu.

Percona Toolkit a analýza MySQL slow logu na Windows

Analýza MySQL slow logu je jedním ze základních a zároveň nejmocnějších způsobů, jak zrychlit web a předejít přetěžování databázového serveru. Jde o to, podívat se na SQL dotazy, které trvaly příliš dlouho a zároveň se často spouštěly a ty pak optimalizovat (indexy nebo jejich přepsáním, sdružením, rozdělením atd).

Používám k tomu nástroj Percona Toolkit, který je ale dostupný pouze pro Linux. Jak se s tím poprat ve Windows 10? Připravil jsem podrobný návod.

Ve zkratce:

  1. Nainstalujeme si Ubuntu subsystém.
  2. Do něj MySQL server.
  3. Ten nakonfigurujeme – změníte mu port, abychom jej mohli používat vedle současného serveru i z WAMPu z Windows!
  4. Nainstalujeme Percona Toolkit.
  5. Do něj nahrajeme slow query log z produkčního serveru.
  6. Stáhneme si nástroj Anemometer.
  7. A budeme analyzovat!

Pokračování textu Percona Toolkit a analýza MySQL slow logu na Windows