Rubriky
Blog

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.