Jak jsem migroval WordPress do Dockeru
Jsou věci, které člověk nemůže odkládat do nekonečně. Placení účtů, příjem vody a jídla, osobní hygiena a v neposlední řadě také migrace WordPress blogu do Dockeru. Jak jsem psal již dříve, přesouvám si veškeré své weby a projekty na svůj server a blog byla jedna z věcí, kterou jsem neustále oddaloval, protože přeci jen vyžadovala více práce než přesun statických webů.
Blog jako takový mi běží na WordPressu, což byla jasná volba po nerozvážném mladistvém období, kdy jsem si redakční systémy pro své blogy programoval sám. Věděl jsem tedy, že budu potřebovat Docker image, který bude obsahovat PHP, databázi a nějaký webserver. I když existuje oficiální image, stejně jsem si chtěl vyzkoušet, jaké to je si image udělat sám, přesně podle mých představ, bez zbytečných věcí kolem. Základem pro výsledek se stal, jako u většiny mých image, Debian Jessie.
První věcí, kterou jsem řešil, byl výběr webserveru. Jelikož jsem s nginxem pracoval již u svého image pro statické stránky, byl jasnou volbou oproti Apache. Protože ale Debian v sobě má Apache od základu, bylo potřeba ho nejdříve odstranit a až poté nainstalovat čistý nginx a přidat upravený konfiurační soubor.
# Remove Apache RUN apt-get remove -y apache2* RUN rm -rf /etc/apache2 # Install nginx RUN apt-get install -y nginx COPY data/nginx.conf /etc/nginx/nginx.conf
Dalším krokem bylo PHP. I když jsem na pár již hotových image pro WordPress s nainstalovaným nginxem narazil, vesměs se jednalo o staré projekty, které moc aktivity nevykazovaly. Abych měl vše pokud možno „up-to-date“, jasnou volbou bylo sáhnout po PHP7. Samotná instalace je opět dílem pár řádek kódu (příjemným zjištěním je, že Docker umí u příkazu ADD pracovat i s URL a není tak třeba instalovat wget nebo curl, pokud není vyžadován i ve výsledku) a nejvíce času mi následně zabrala optimální konfigurace, aby WordPress běžel co nejsvižněji a zjišťování, jaké PHP balíčky vlastně potřebuje.
# Add repository for PHP7 RUN echo 'deb http://packages.dotdeb.org jessie all' >> /etc/apt/sources.list ADD https://www.dotdeb.org/dotdeb.gpg /tmp/dotdeb.gpg RUN apt-key add /tmp/dotdeb.gpg RUN rm -f /tmp/dotdeb.gpg RUN apt-get update # Install PHP7 RUN apt-get install -y php7.0-fpm php7.0-mysql php7.0-gd php7.0-curl php7.0-imagick php7.0-imap php7.0-mcrypt php7.0-xmlrpc COPY data/www.conf /etc/php/7.0/fpm/pool.d
Poslední na řadě byla databáze. I když u některých svých menších projektů používám SQLite uloženým v jednom souboru, zde jsem zvolil něco robustnějšího, konkrétně MariaDB (čistě ze zvědavosti a touhy vyzkoušet „lepšího“ bráchu MySQL). Ve výsledku to člověk ani nijak nepozná, protože vše se stále ovládá přes mysql příkaz a všechny věci, co jsem zkoušel, fungovaly úplně stejně jako u MySQL.
# Install MariaDB RUN apt-get install -y mariadb-server mariadb-client COPY data/my.cnf /etc/mysql/ VOLUME /var/lib/mysql
Tímto jsem tedy měl nainstalovanou „svatou trojici“ potřebnou pro běh a zbývalo přidání nějakého „startéru“ a hlavně samotného WordPressu. U všech již hotových řešení jsem narazil na jeden pro mě neduh, že se WordPress stahoval již během buildění image. Tím pádem v něm obsažená verze byla vždy aktuální k datu vytvoření image, což u starších projektů mohlo být pár let. Tento přístup se mi nelíbil a proto jsem se rozhodl WordPress stahovat, až při vytváření nového containeru.
# WordPress configuration is done only if config file doesn't exist if [ ! -f /var/www/wp-config.php ]; then # Download latest WordPress curl -o /tmp/wp.tar.gz https://wordpress.org/latest.tar.gz # Un-tar it tar xf /tmp/wp.tar.gz -C /var/www/ --strip-components=1 # Generate passwords for database and WordPress MYSQL_PASSWORD=`pwgen -c -n -1 15` WORDPRESS_PASSWORD=`pwgen -c -n -1 15` # Set MySQL root password mysqladmin -u root password $MYSQL_PASSWORD # Create user and database for WordPress WORDPRESS_DB="wordpress" WORDPRESS_USER="wordpress" mysql -u root -p$MYSQL_PASSWORD -e "CREATE USER $WORDPRESS_USER@localhost IDENTIFIED BY '$WORDPRESS_PASSWORD';" mysql -u root -p$MYSQL_PASSWORD -e "CREATE DATABASE $WORDPRESS_DB;" mysql -u root -p$MYSQL_PASSWORD -e "GRANT ALL PRIVILEGES ON $WORDPRESS_DB.* TO $WORDPRESS_USER@localhost IDENTIFIED BY '$WORDPRESS_PASSWORD';" mysql -u root -p$MYSQL_PASSWORD -e "FLUSH PRIVILEGES;" echo "MySQL root password: $MYSQL_PASSWORD" echo "Wordpress user: $WORDPRESS_USER" echo "Wordpress password: $WORDPRESS_PASSWORD" echo "Wordpress database: $WORDPRESS_DB" # Edit config file sed -e "s/database_name_here/$WORDPRESS_DB/ s/username_here/$WORDPRESS_USER/ s/password_here/$WORDPRESS_PASSWORD/ /'AUTH_KEY'/s/put your unique phrase here/`pwgen -c -n -1 65`/ /'SECURE_AUTH_KEY'/s/put your unique phrase here/`pwgen -c -n -1 65`/ /'LOGGED_IN_KEY'/s/put your unique phrase here/`pwgen -c -n -1 65`/ /'NONCE_KEY'/s/put your unique phrase here/`pwgen -c -n -1 65`/ /'AUTH_SALT'/s/put your unique phrase here/`pwgen -c -n -1 65`/ /'SECURE_AUTH_SALT'/s/put your unique phrase here/`pwgen -c -n -1 65`/ /'LOGGED_IN_SALT'/s/put your unique phrase here/`pwgen -c -n -1 65`/ /'NONCE_SALT'/s/put your unique phrase here/`pwgen -c -n -1 65`/" /var/www/wp-config-sample.php > /var/www/wp-config.php # Configure permissions for WordPress chown -R www-data:www-data /var/www/ find /var/www/ -type d -exec chmod 755 {} \; find /var/www/ -type f -exec chmod 644 {} \; # Enable direct access to files echo "define('FS_METHOD', 'direct');" >> /var/www/wp-config.php fi
Velkou inspirací mi v tomto bodě byl jbfink/docker-wordpress, který vyřešil složitější věci s uložením konfigurace a generováním databáze a hesel.
Velkým požadavkem na celkovou funkčnost bylo, aby data byla persistentní, tj. abych mohl s klidný svědomím vyměnit container za novější verzi a nemusel se bát, že přijdu o nahrané soubory nebo napsané články. Z toho důvodu ukládám instalaci WordPressu na hostující systém a pro databázi mám vytvořený volume, který stačí pouze mountnout do nově vytvářeného image.
No a jaký je tedy výsledek? Výsledkem je nový repozitář na Docker Hubu pavelsterba/dockerpress, na jehož latest verzi běží i tento blog. Nechám na zvážení, pokud ho někdo bude chtít nasadit i pro svůj web, seznam issues, na které narazím, vedu veřejně.