{"id":20140640,"url":"https://github.com/goffinet/lab-automation-wordpress","last_synced_at":"2026-04-12T03:35:08.367Z","repository":{"id":116034284,"uuid":"215410877","full_name":"goffinet/lab-automation-wordpress","owner":"goffinet","description":"Lab Automation LAMP Wordpress","archived":false,"fork":false,"pushed_at":"2019-10-17T09:54:08.000Z","size":324,"stargazers_count":1,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-07-14T00:08:36.939Z","etag":null,"topics":["ansible","bash","centos","docker","fedora","helm","k8s","lab","lamp","terraform","ubuntu","wordpress"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/goffinet.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-10-15T22:54:08.000Z","updated_at":"2019-12-23T00:37:17.000Z","dependencies_parsed_at":null,"dependency_job_id":"bb12b858-3a4c-4f0f-98f6-5f0202f353da","html_url":"https://github.com/goffinet/lab-automation-wordpress","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/goffinet/lab-automation-wordpress","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goffinet%2Flab-automation-wordpress","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goffinet%2Flab-automation-wordpress/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goffinet%2Flab-automation-wordpress/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goffinet%2Flab-automation-wordpress/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/goffinet","download_url":"https://codeload.github.com/goffinet/lab-automation-wordpress/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goffinet%2Flab-automation-wordpress/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31703501,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-11T21:17:31.016Z","status":"online","status_checked_at":"2026-04-12T02:00:06.763Z","response_time":58,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","bash","centos","docker","fedora","helm","k8s","lab","lamp","terraform","ubuntu","wordpress"],"created_at":"2024-11-13T21:52:57.585Z","updated_at":"2026-04-12T03:35:08.349Z","avatar_url":"https://github.com/goffinet.png","language":"Shell","readme":"---\ndescription: \"Voici un lab progressif Linux Apache MySQL/MariaDB PHP (LAMP) avec l'application Wordpress sur un seul serveur. L'exercice démarre à partir d'un tutorial improbable pour se terminer en script Bash supporté par plusieurs distribution, l'activation des sécurités de base comme le pare-feu, les mots de passe ou encore HTTPS Lets Encrypt. Par François Goffinet.\"\ntype: docs\n---\n\n# Lab Automation LAMP Wordpress\n\n\u003c!-- TOC depthFrom:2 depthTo:6 withLinks:1 updateOnSave:1 orderedList:0 --\u003e\n\n- [1. Premiers essais](#1-premiers-essai)\n\t- [1.1. Méthodologie et consigne](#11-mthodologie-et-consigne)\n\t- [1.2. Apache](#12-apache)\n\t\t- [Installation et activation](#installation-et-activation)\n\t\t- [Tests](#tests)\n\t\t- [GET HTTP](#get-http)\n\t\t- [HEAD HTTP](#head-http)\n\t\t- [Configuration courante](#configuration-courante)\n\t\t- [Hôtes virtuels](#htes-virtuels)\n\t- [1.4. Base de données](#14-base-de-donnes)\n\t\t- [Tests](#tests)\n\t\t- [mysql_secure_installation](#mysqlsecureinstallation)\n\t- [1.5. Installation de PHP](#15-installation-de-php)\n\t- [1.6. Problématiques rencontrées](#16-problmatiques-rencontres)\n\t\t- [PHP-FPM](#php-fpm)\n\t\t- [Pare-feu](#pare-feu)\n\t- [1.7. Téléchargement de Wordpress](#17-tlchargement-de-wordpress)\n\t- [1.8. Création de la base de données de Wordpress](#18-cration-de-la-base-de-donnes-de-wordpress)\n\t- [1.9. Configurer Wordpress](#19-configurer-wordpress)\n\t- [1.10. Installer Worpdress](#110-installer-worpdress)\n\t- [1.11. Nettoyer ses opérations](#111-nettoyer-ses-oprations)\n- [2. Améliorations et automatisations](#2-amliorations-et-automatisations)\n\t- [2.1. Installation, configuration et lancement du stack LAMP](#21-installation-configuration-et-lancement-du-stack-lamp)\n\t- [2.2. Création de la base de donnée](#22-cration-de-la-base-de-donne)\n\t- [2.3. Tests des services](#23-tests-des-services)\n\t- [2.4. Installation de Wordpress](#24-installation-de-wordpress)\n- [3. Script fonctionnel](#3-script-fonctionnel)\n\t- [3.1. Mise en variables](#31-mise-en-variables)\n\t- [3.2. Installation des logiciels](#32-installation-des-logiciels)\n\t- [3.3. démarrage des services](#33-dmarrage-des-services)\n\t- [3.4. Ouverture du par-feu](#34-ouverture-du-par-feu)\n\t- [3.5. Sécuriser Mariabd et le configurer pour Wordpress](#35-scuriser-mariabd-et-le-configurer-pour-wordpress)\n\t- [3.6. Enregistrement des mots de passe](#36-enregistrement-des-mots-de-passe)\n\t- [3.7. Tests du stack](#37-tests-du-stack)\n- [4. WP-CLI](#4-wp-cli)\n\t- [4.1 Installation de wp-cli](#41-installation-de-wp-cli)\n\t- [4.2. Vérifier le fonctionnement de wp-cli](#42-vrifier-le-fonctionnement-de-wp-cli)\n\t- [4.3. Télécharger Worpdress](#43-tlcharger-worpdress)\n\t- [4.4. Création du fichier de configuration](#44-cration-du-fichier-de-configuration)\n\t- [4.4. Créer la base de données Wordpress](#44-crer-la-base-de-donnes-wordpress)\n\t- [4.6. Installation de Wordpress](#46-installation-de-wordpress)\n\t- [4.7. Mise-à-jour de tous les plugins dans leur dernière version](#47-mise-jour-de-tous-les-plugins-dans-leur-dernire-version)\n\t- [4.8. Affichage des informations](#48-affichage-des-informations)\n\t- [4.9. Résumé du déploiement de Wordpress](#49-rsum-du-dploiement-de-wordpress)\n\t- [4.10. Programme principal](#410-programme-principal)\n\t- [4.11. Améliorations et optimisations](#411-amliorations-et-optimisations)\n- [5. Déploiement de la solution sur Centos 7 et Ubuntu](#5-dploiement-de-la-solution-sur-centos-7-et-ubuntu)\n\t- [5.1. Déploiement Centos7](#51-dploiement-centos7)\n\t- [5.2. Déploiement sur Ubuntu](#52-dploiement-sur-ubuntu)\n\t- [5.2. Allow-root WP-CLI](#52-allow-root-wp-cli)\n\t- [5.3. Appel aux fonctions selon la distribution](#53-appel-aux-fonctions-selon-la-distribution)\n- [6. Support HTTPS Let's Encrypt](#6-support-https-lets-encrypt)\n\t- [6.1. Virtual Hosts](#61-virtual-hosts)\n\t- [6.2. Fichier vhost pour Centos / Fedora](#62-fichier-vhost-pour-centos-fedora)\n\t- [6.4. Fichier vhost pour Debian / Ubuntu](#64-fichier-vhost-pour-debian-ubuntu)\n\t- [6.5. Mise en commun de la configuration vhost](#65-mise-en-commun-de-la-configuration-vhost)\n\t- [6.6. Certbot Let's Encrypt](#66-certbot-lets-encrypt)\n- [7. Déploiement Wordpress Haute Disponiblité](#7-dploiement-wordpress-haute-disponiblit)\n- [8. Déploiement sur Docker](#8-dploiement-sur-docker)\n- [9. Approvisionnement Ansible](#9-approvisionnement-ansible)\n- [10. Application Stateful Wordpress sur un cluster Kubernetes](#10-application-stateful-wordpress-sur-un-cluster-kubernetes)\n- [11. Script final](#11-script-final)\n\n\u003c!-- /TOC --\u003e\n\n\nVous vous initiez à l'administration DevOps du [moteur de blogging Wordpress](https://fr.wikipedia.org/wiki/WordPress). Dans une première approche vous cherchez un base pour commencer votre déploiement. Vous choisissez un article dont le nom est évocateur : [How to Install LAMP Stack on Fedora 27](https://linoxide.com/linux-how-to/install-lamp-stack-fedora-27/). Car la machine qui est approvisionnée chez [Scaleway est un DEV1-S](https://www.scaleway.com/fr/instances-virtuelles/development/) avec une image Fedora 27.\n\nVous démarrez donc en [Fedora 27](https://linux.goffinet.org/01-02-distributions-linux-et-cycles-de-maintenance/#72-fedora) pour déployer un serveur Wordpress basé sur le [stack LAMP](https://fr.wikipedia.org/wiki/LAMP).\n\n## 1. Premiers essai\n\nÀ la lecture du tuto, la procédure se résume en deux étapes principales auxquelles correspondent les tâches suivantes.\n\n1. Déploiement du stack LAMP\n  1. Installation et test du serveur Web\n  2. Installation et sécurisation du service de base données\n  3. Installation et test de PHP\n2. Déploiement de l'application Wordpress\n  1. Téléchargement de Wordpress\n  2. Création de la base de données de Wordpress\n  3. Création du fichier de configuration de wordpress\n  4. Installation manuelle de Wordpress\n\n### 1.1. Méthodologie et consigne\n\nExécutez chaque commande opérationnelle. Copiez les actions qui s'exécutent avec succès dans un fichier destiné à devenir un script d'automatisation Bash.\n\nVeuillez également exécuter les commandes de diagnostic, évaluer celles qui conviennent le mieux à des tests et les retenir dans votre fichier de travail.\n\n### 1.2. Apache\n\n#### Installation et activation\n\n```bash\ndnf install httpd\n```\n\n```bash\nsystemctl enable httpd.service\nsystemctl start httpd.service\n```\n#### Tests\n\nApache :\n\n```bash\nsystemctl status httpd\n```\n\n```bash\njournalctl -f -l -u httpd\n```\n```bash\ntail /var/log/httpd/error_log\n```\n\n```bash\nhttpd -V\n```\n\non peut demander à curl de rendre un résultat sur le serveur Web. En effet, le dossier par défaut des pages à servir est `/var/www/html`. En l'absence d'un fichier d'index par défaut, une page \"noindex\" est servie à partir de l'emplacement `/usr/share/httpd/`.\n\n#### GET HTTP\n\n```bash\ncurl -G http://127.0.0.1\n\u003c!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\"\u003e\n\n\u003chtml xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\"\u003e\n\t\u003chead\u003e\n\t\t\u003ctitle\u003eTest Page for the Apache HTTP Server on Fedora\u003c/title\u003e\n    ...\n```\n\n#### HEAD HTTP\n\n```bash\necho \"OK\" \u003e /var/www/html/test\n```\n```bash\ncurl -I http://127.0.0.1/\nHTTP/1.1 200 OK\nDate: Sun, 18 Nov 2018 12:07:14 GMT\nServer: Apache/2.4.34 (Fedora)\nLast-Modified: Sun, 18 Nov 2018 12:07:10 GMT\nETag: \"3-57aef3d7c776a\"\nAccept-Ranges: bytes\nContent-Length: 3\nContent-Type: text/html; charset=UTF-8\n```\n```bash\ncurl -G http://127.0.0.1/test\nOK\n```\n\n#### Configuration courante\n\nOn sera curieux d'examiner la configuration du serveur Web située dans l'emplacement `/etc/httpd`.\n\n```bash\negrep -v '^$|^[[:blank:]]*#' /etc/httpd/conf/httpd.conf\n```\n```\nServerRoot \"/etc/httpd\"\nListen 80\nInclude conf.modules.d/*.conf\nUser apache\nGroup apache\nServerAdmin root@localhost\n\u003cDirectory /\u003e\n    AllowOverride none\n    Require all denied\n\u003c/Directory\u003e\nDocumentRoot \"/var/www/html\"\n\u003cDirectory \"/var/www\"\u003e\n    AllowOverride None\n    Require all granted\n\u003c/Directory\u003e\n\u003cDirectory \"/var/www/html\"\u003e\n    Options Indexes FollowSymLinks\n    AllowOverride None\n    Require all granted\n\u003c/Directory\u003e\n\u003cIfModule dir_module\u003e\n    DirectoryIndex index.html\n\u003c/IfModule\u003e\n\u003cFiles \".ht*\"\u003e\n    Require all denied\n\u003c/Files\u003e\nErrorLog \"logs/error_log\"\nLogLevel warn\n\u003cIfModule log_config_module\u003e\n    LogFormat \"%h %l %u %t \\\"%r\\\" %\u003es %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\"\" combined\n    LogFormat \"%h %l %u %t \\\"%r\\\" %\u003es %b\" common\n    \u003cIfModule logio_module\u003e\n      LogFormat \"%h %l %u %t \\\"%r\\\" %\u003es %b \\\"%{Referer}i\\\" \\\"%{User-Agent}i\\\" %I %O\" combinedio\n    \u003c/IfModule\u003e\n    CustomLog \"logs/access_log\" combined\n\u003c/IfModule\u003e\n\u003cIfModule alias_module\u003e\n    ScriptAlias /cgi-bin/ \"/var/www/cgi-bin/\"\n\u003c/IfModule\u003e\n\u003cDirectory \"/var/www/cgi-bin\"\u003e\n    AllowOverride None\n    Options None\n    Require all granted\n\u003c/Directory\u003e\n\u003cIfModule mime_module\u003e\n    TypesConfig /etc/mime.types\n    AddType application/x-compress .Z\n    AddType application/x-gzip .gz .tgz\n    AddType text/html .shtml\n    AddOutputFilter INCLUDES .shtml\n\u003c/IfModule\u003e\nAddDefaultCharset UTF-8\n\u003cIfModule mime_magic_module\u003e\n    MIMEMagicFile conf/magic\n\u003c/IfModule\u003e\nEnableSendfile on\nIncludeOptional conf.d/*.conf\n```\n\n#### Hôtes virtuels\n\nOn s'intéressera au concept [d'hôte virtuel](https://linux.goffinet.org/31_services_apache_http_server/#7-serveurs-virtuels-par-nom).\n\n### 1.4. Base de données\n\n#### Tests\n\nMariadb :\n\n```bash\ndnf install mariadb-server\n```\n```bash\nsystemctl start mariadb.service\nsystemctl enable mariadb.service\n```\n\n```bash\nsystemctl status mariadb.service\nmysql -V\n```\n\n```bash\nss -tlp | egrep 'http|mysql'\nLISTEN   0         80                        *:mysql                  *:*        users:((\"mysqld\",pid=4972,fd=37))\nLISTEN   0         128                       *:http                   *:*        users:((\"httpd\",pid=6206,fd=4),(\"httpd\",pid=5457,fd=4),(\"httpd\",pid=5456,fd=4),(\"httpd\",pid=5455,fd=4),(\"httpd\",pid=5201,fd=4))\n```\n\n#### mysql_secure_installation\n\nAvant de l'utiliser, il est de bonne pratique de sécuriser un service de base de données MYSQL.\n\n```bash\nmysql_secure_installation\n```\n\n```bash\nNOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB\n      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!\n\nIn order to log into MariaDB to secure it, we'll need the current\npassword for the root user.  If you've just installed MariaDB, and\nyou haven't set the root password yet, the password will be blank,\nso you should just press enter here.\n\nEnter current password for root (enter for none):\nOK, successfully used password, moving on...\n\nSetting the root password ensures that nobody can log into the MariaDB\nroot user without the proper authorisation.\n\nSet root password? [Y/n] Y\nNew password:\nRe-enter new password:\nPassword updated successfully!\nReloading privilege tables..\n ... Success!\n\n\nBy default, a MariaDB installation has an anonymous user, allowing anyone\nto log into MariaDB without having to have a user account created for\nthem.  This is intended only for testing, and to make the installation\ngo a bit smoother.  You should remove them before moving into a\nproduction environment.\n\nRemove anonymous users? [Y/n] y\n ... Success!\n\nNormally, root should only be allowed to connect from 'localhost'.  This\nensures that someone cannot guess at the root password from the network.\n\nDisallow root login remotely? [Y/n] y\n ... Success!\n\nBy default, MariaDB comes with a database named 'test' that anyone can\naccess.  This is also intended only for testing, and should be removed\nbefore moving into a production environment.\n\nRemove test database and access to it? [Y/n] y\n - Dropping test database...\n ... Success!\n - Removing privileges on test database...\n ... Success!\n\nReloading the privilege tables will ensure that all changes made so far\nwill take effect immediately.\n\nReload privilege tables now? [Y/n] y\n ... Success!\n\nCleaning up...\n\nAll done!  If you've completed all of the above steps, your MariaDB\ninstallation should now be secure.\n\nThanks for using MariaDB!\n```\n\n### 1.5. Installation de PHP\n\n```bash\ndnf install php php-common\n```\n```bash\ndnf install php php-common php-mysqlnd php-gd php-imap php-xml php-cli php-opcache php-mbstring\n```\n\n```bash\nsystemctl restart httpd\ncd /var/www/html\necho \"\u003c?php phpinfo(); ?\u003e\" \u003e\u003e info.php\ncurl http://127.0.0.1/info.php\n```\n\nNotons que c'est la **version 7.2 de PHP** qui est en fonction.\n\nExamen de la page `info.php`.\n\n![info.php](pictures/phpinfo-fedora27-lamp.jpg)\n\n### 1.6. Problématiques rencontrées\n\n[Dépot Remi](https://blog.remirepo.net/pages/Presentation) : https://blog.remirepo.net/pages/Config\n\n#### PHP-FPM\n\nPHP-FPM : voir [Utiliser Apache avec PHP-FPM](https://villalard.net/utiliser-apache-avec-php-fpm)\n\n```bash\ncurl http://127.0.0.1/info.php\n\u003c!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\"\u003e\n\u003chtml\u003e\u003chead\u003e\n\u003ctitle\u003e503 Service Unavailable\u003c/title\u003e\n\u003c/head\u003e\u003cbody\u003e\n\u003ch1\u003eService Unavailable\u003c/h1\u003e\n\u003cp\u003eThe server is temporarily unable to service your\nrequest due to maintenance downtime or capacity\nproblems. Please try again later.\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e\n```\n\nAu lieu d'obtenir la \"belle\" page info.php, on obtient un message d'erreur **503 Service Unavailable** qui renseigne une erreur du côté du serveur ([Codes de retour HTTP](https://linux.goffinet.org/30_services_web/#74-codes-de-retour))\n\n```bash\ntail /var/log/httpd/error_log -n2\n[Sun Nov 18 12:25:52.916813 2018] [proxy:error] [pid 5207:tid 140606827362048] (2)No such file or directory: AH02454: FCGI: attempt to connect to Unix domain socket /run/php-fpm/www.sock (*) failed\n[Sun Nov 18 12:25:52.916891 2018] [proxy_fcgi:error] [pid 5207:tid 140606827362048] [client 127.0.0.1:36686] AH01079: failed to make connection to backend: httpd-UDS\n```\n\nLes logs httpd nous indiquent une erreur php-fpm.\n\n```bash\nls /run/php-fpm/www.sock\nls: cannot access '/run/php-fpm/www.sock': No such file or directory\n[root@devlab90 html]# ls /run/php-fpm\nls: cannot access '/run/php-fpm': No such file or directory\n```\n\nCe fichier `/run/php-fpm/www.sock` n'existe pas.\n\n```bash\ntail -n3 /var/log/php-fpm/error.log\n[18-Nov-2018 12:25:50] ERROR: FPM initialization failed\n[18-Nov-2018 12:28:15] ERROR: [pool www] failed to read the ACL of the socket '/run/php-fpm/www.sock': Operation not supported (95)\n[18-Nov-2018 12:28:15] ERROR: FPM initialization failed\n```\n\n```bash\nsed -i 's/listen.acl_users/;listen.acl_users/g' /etc/php-fpm.d/www.conf\n```\n\nEn commentant la ligne qui contient `listen.acl_users`, le service redémarre.\n\n```bash\nsystemctl start php-fpm\nsystemctl status php-fpm\n```\n\n```bash\ncurl http://127.0.0.1/info.php\n\u003c!DOCTYPE HTML PUBLIC \"-//IETF//DTD HTML 2.0//EN\"\u003e\n\u003chtml\u003e\u003chead\u003e\n\u003ctitle\u003e503 Service Unavailable\u003c/title\u003e\n\u003c/head\u003e\u003cbody\u003e\n\u003ch1\u003eService Unavailable\u003c/h1\u003e\n\u003cp\u003eThe server is temporarily unable to service your\nrequest due to maintenance downtime or capacity\nproblems. Please try again later.\u003c/p\u003e\n\u003c/body\u003e\u003c/html\u003e\n```\n\nMais l'erreur serveur ne disparaît qu'en fixant les droits de l'utilisateur apache sur le fichier du pool PHP-FPM `/run/php-fpm/www.sock`.\n\n```bash\nchown apache:apache /run/php-fpm/www.sock\n```\n\n```bash\ncurl http://127.0.0.1/info.php\n```\n\n#### Pare-feu\n\nComment joindre le serveur de l'extérieur ?\n\n```bash\nip=$(curl -s -G http://ipinfo.io/ip)\nurl=\"http://www.${ip}.xip.io/\"\n```\n\n```bash\necho $url\n```\n\nLe stack est-il accessible de l'extérieur ? En Fedora dans lequel le pare-feu est activé par défaut, probablement.\n\n```bash\nfirewall-cmd --list-services\n```\n\nIl est nécessaire d'ouvrir le pare-feu, par exemple en ajoutant le service \"http\" au profil de filtrage par défaut \"public\".\n\n```bash\nfirewall-cmd --zone=public --permanent --add-service=http\nfirewall-cmd --reload\n```\nComment pourrait-on tester le site sans ouvrir le pare-feu, uniquement avec une connexion SSH ?\n\nEn transférant le port local TCP80 sur un port de l'ordinateur qui se connecte ici par exemple TCP8888.\n\n```bash\nssh -L 8888:127.0.0.1:80 root@votres_serveur\n```\n\n### 1.7. Téléchargement de Wordpress\n\nCette étape demande des compétences d'administration \"traditionnelle\".\n\n```bash\ndnf install wget\nwget http://wordpress.org/latest.tar.gz\ntar xvfz latest.tar.gz -C /var/www/html/\n```\n\n### 1.8. Création de la base de données de Wordpress\n\nLa procédure consiste à se connecter à la base de données en tant qu'utilisateur \"root\" de la base de données et à encoder les commandes suivantes qui créent un utilisateur avec un mot de passe à modifier (\"testadmin208\"), qui créent une base de données et qui lient l'utilisateur à la base de donnée.\n\n```bash\nmysql -u root -p\n```\n\nDans le shell mysql, voici les commandes à encoder :\n\n```mysql\nCREATE USER wpuser@localhost IDENTIFIED BY \"testadmin208\";\nCREATE DATABASE wp_database;\nGRANT ALL ON wp_database.* TO wpuser@localhost;\nFLUSH PRIVILEGES;\nquit\n```\n\n### 1.9. Configurer Wordpress\n\nIl s'agit ici d'indiquer les paramètres de la base de données créée dans l'étape précédente dans un fichier `wp-config.php` en se servant du modèle `wp-config-sample.php`.\n\n```bash\ncd /var/www/html/wordpress/\ncp wp-config-sample.php wp-config.php\n```\n\nEnsuite, modifier les paramètres à l'aide de `vi` :\n\n```\ndefine('DB_NAME', 'wp_database');\ndefine('DB_USER', 'wpuser');\ndefine('DB_PASSWORD', 'testadmin208');\ndefine('DB_HOST', 'localhost');\n```\n\n### 1.10. Installer Worpdress\n\nLa suite de l'installation se déroule dans l'interface Web. Entretemps, le site reste vulnérable.\n\n```bash\ncurl http://127.0.0.1/wordpress/\n```\n\n### 1.11. Nettoyer ses opérations\n\nLe script `clean-lamp.sh` se propose de nettoyer grossièrement ces opérations.\n\n```bash\n#! /bin/bash\n# clean-lamp.sh\nsystemctl stop httpd mariadb php-fpm\nsystemctl disable httpd mariadb php-fpm\ndnf -y remove mariadb mariadb-server httpd php-fpm\nrm -rf /var/lib/mysql\nrm -r /etc/my.cnf\nrm -r ~/.my.cnf\nrm -rf /var/www/html/*\nfirewall-cmd --zone=public --permanent --remove-service=http\nfirewall-cmd --reload\n```\n\n## 2. Améliorations et automatisations\n\nDans cet exercice, on reprendra les opérations dans une perspective d'automation qui regroupe les tâches dans des étapes distinctes. Un seul mot de passe est choisi \"Yj7tXc1Ml\". La perspective reste séquentielle.\n\nOn tentera de rassembler les opérations logiques en étapes : installation, configuration, lancement, test, ... La procédure d'installation de Wordpress peut elle-même être divisée en quelques étapes.\n\n* Installation, configuration et lancement du stack LAMP\n* Création de la base de donnée\n* Test des services\n* Installation de Wordpress\n\n### 2.1. Installation, configuration et lancement du stack LAMP\n\nEn regroupes les tâches d'installation, de configuration et de lancement des services LAMP, la configuration du pare-feu.\n\n```bash\n# Choose a password for root and wpuser database : \"Yj7tXc1Ml\"\n# LAMP Stack installation and dependencies\ndnf -y install httpd mariadb-server php php-mysqlnd php-json wget\n# Configure php-fpm\nsed -i 's/listen.acl_users/;listen.acl_users/g' /etc/php-fpm.d/www.conf\n# Enable and start services\nsystemctl enable httpd mariadb php-fpm\nsystemctl start httpd mariadb php-fpm\nchown apache:apache /run/php-fpm/www.sock\n# Open the HTTP port TCP 80\nfirewall-cmd --zone=public --permanent --add-service=http\nfirewall-cmd --reload\n```\n\n### 2.2. Création de la base de donnée\n\nLa base de données Wordpress est créée et configurée après avoir sécurisé le service.\n\n```bash\n# See https://stackoverflow.com/questions/24270733/automate-mysql-secure-installation-with-echo-command-via-a-shell-script\n# See https://gist.github.com/Mins/4602864\n# mysql_secure_installation as model\n# Make sure that NOBODY can access the server without a password\nmysql -e \"UPDATE mysql.user SET Password = PASSWORD('Yj7tXc1Ml') WHERE User = 'root'\"\n# Kill the anonymous users\nmysql -e \"DROP USER ''@'localhost'\"\n# Because our hostname varies we'll use some Bash magic here.\nmysql -e \"DROP USER ''@'$(hostname)'\"\n# Kill off the demo database\nmysql -e \"DROP DATABASE test\"\n# Create wpuser\nmysql -e \"CREATE USER wpuser@localhost IDENTIFIED BY 'Yj7tXc1Ml';\"\n# Create wp_database\nmysql -e \"CREATE DATABASE wp_database;\"\n# Fix wpuser rights on wp_database\nmysql -e \"GRANT ALL ON wp_database.* TO wpuser@localhost;\"\n# Make our changes take effect\nmysql -e \"FLUSH PRIVILEGES\"\necho 'root password : Yj7tXc1Ml' \u003e /root/.wpsecrets\necho 'wpuser password : Yj7tXc1Ml' \u003e\u003e /root/.wpsecrets\nchmod 600 /root/.wpsecrets\n```\n\nRemarquez que le mot de passe est enregistré dans le fichier caché `/root/.wpsecrets`\n\n### 2.3. Tests des services\n\n```bash\n# Test Apache\nif [ $(curl -s -I 127.0.0.1 | grep -q 'Server: Apache/2.4.34 (Fedora)' ; echo $?) == '0' ] ; then\necho \"Apache is working\" ; else\necho \"Apache is NOT working\" ; fi\n```\n\n```bash\n# Test PHP\necho \"\u003c?php phpinfo(); ?\u003e\" \u003e /var/www/html/info.php\nif [ $(curl -s -G http://127.0.0.1/info.php | grep -q 'phpinfo' ; echo $?) == '0' ] ; then\necho \"PHP is working\" ; else\necho \"PHP is NOT working\" ; fi\n#rm -f /var/www/html/info.php\n```\n\n### 2.4. Installation de Wordpress\n\n```bash\n# Download Wordpress lastest version\nwget http://wordpress.org/latest.tar.gz\ntar xvfz latest.tar.gz -C /var/www/html/\ncp /var/www/html/wordpress/wp-config-sample.php /var/www/html/wordpress/wp-config.php\nsed -i 's/database_name_here/wp_database/g' /var/www/html/wordpress/wp-config.php\nsed -i 's/username_here/wpuser/g' /var/www/html/wordpress/wp-config.php\nsed -i 's/password_here/Yj7tXc1Ml/g' /var/www/html/wordpress/wp-config.php\n# Configure your application\necho \"Go to http://$(curl -s https://ipinfo.io/ip).xip.io/wordpress/ to configure your application\"\n```\n\n## 3. Script fonctionnel\n\nL'exercice précédent consistait à reprendre les lignes de commandes manuelles et à les automatiser.\n\nToutefois, on peut suggérer quelques optimisations qui rendraient la procédure plus évolutive et plus robuste.\n\n* Les étapes logiques pourraient être présentées sous forme de fonctions.\n* Toute une série de paramètres pourraient subir une mise en variable.\n* La gestion des mots de passe est un enjeu ici. Leur choix aléatoire devrait aider l'utilisateur. La question de leur confidentialité (_a secret_ en anglais) se pose.\n* Enfin la seconde étape d'installation de Wordpress semble peu robuste. On proposera ici d'utiliser le binaire `wp-cli` pour gérer le moteur de blog.\n\nVoici un troisième exercice qui illustre ces optimisations.\n\n### 3.1. Mise en variables\n\nL'adresse IP du site, son [FQDN](https://fr.wikipedia.org/wiki/Fully_qualified_domain_name), son titre, les utilisateurs \"admin\" (utilisateur de gestion) et \"dbuser\" (utilisateur de la base de données), l'emplacement de l'application, les mots de passe (générés de manière aléatoire) sont susceptibles d'être mis en paramètres.\n\n```bash\nip_adress=$(curl -s https://ipinfo.io/ip)\nsite_title=\"Demo Wordpress\"\nsite_url=\"http://www.${ip_adress}.xip.io\"\napplication_path=\"/var/www/html\"\nadmin_email=\"test@test.com\"\nadmin_user=\"admin\"\nadmin_password=$(pwmake 128 | head -c12)\ndbuser=\"wpuser\"\ndbroot_password=$(pwmake 128 | head -c12)\ndbuser_password=$(pwmake 128 | head -c12)\n\n```\n\n### 3.2. Installation des logiciels\n\nInstallation des logiciels et adaptation du fichier `/etc/php-fpm.d/www.conf`.\n\n```bash\nsoftware_installation() {\n# LAMP Stack installation and dependencies\ndnf -y install httpd mariadb-server php php-mysqlnd php-json curl python\n# Work around php-fpm config due the lack of apache config\nsed -i 's/listen.acl_users/;listen.acl_users/g' /etc/php-fpm.d/www.conf\n}\n```\n\n### 3.3. démarrage des services\n\nOn donnera les droits aux utilisateur et groupe `apache` sur le fichier `/run/php-fpm/www.sock`.\n\n```bash\nenable_start_services() {\n# Enable and start services\nsystemctl enable httpd mariadb php-fpm\nsystemctl start httpd mariadb php-fpm\nchown apache:apache /run/php-fpm/www.sock\n}\n```\n\n### 3.4. Ouverture du par-feu\n\n```bash\nopen_firewall() {\n# Open the HTTP port TCP 80\nfirewall-cmd --zone=public --permanent --add-service=http\nfirewall-cmd --reload\n}\n```\n\n### 3.5. Sécuriser Mariabd et le configurer pour Wordpress\n\nIl s'agit de profiter de l'absence de mot de passe sur le compte root pour créer la base et l'utilisateur Wordpress.\n\n```bash\nwordpress_database_creation() {\n# Create dbuser\nmysql -e \"CREATE USER ${dbuser}@localhost IDENTIFIED BY '${dbuser_password}';\"\n# Create wp_database\nmysql -e \"CREATE DATABASE wp_database;\"\n# Fix dbuser rights on wp_database\nmysql -e \"GRANT ALL ON wp_database.* TO ${dbuser}@localhost;\"\n# Make our changes take effect\nmysql -e \"FLUSH PRIVILEGES\"\n}\n```\n\n```bash\nmysql_secure() {\n# mysql_secure_installation as model\n# Make sure that NOBODY can access the server without a password\nmysql -e \"UPDATE mysql.user SET Password = PASSWORD('${dbroot_password}') WHERE User = 'root'\"\n# Kill the anonymous users\nmysql -e \"DROP USER ''@'localhost'\"\n# Because our hostname varies we'll use some Bash magic here.\nmysql -e \"DROP USER ''@'$(hostname)'\"\n# Kill off the demo database\nmysql -e \"DROP DATABASE test\"\n# Make our changes take effect\nmysql -e \"FLUSH PRIVILEGES\"\n}\n```\n\n### 3.6. Enregistrement des mots de passe\n\n```bash\nstore_passwords() {\necho \"dbroot_password=${dbroot_password}\" \u003e /root/.wpsecrets\necho \"dbuser_password=${dbuser_password}\" \u003e\u003e /root/.wpsecrets\necho \"admin_password=${admin_password}\" \u003e\u003e /root/.wpsecrets\nchmod 600 /root/.wpsecrets\n}\n```\n\n### 3.7. Tests du stack\n\n```bash\ntest_stack() {\n# Test Apache\nif [ $(curl -s -I 127.0.0.1 | grep -q 'Server: Apache/2.4.34 (Fedora)' ; echo $?) == '0' ] ; then\necho \"Apache is working\" ; else\necho \"Apache is NOT working\" ; break ; fi\napachectl -V\n\n# Test PHP\necho \"\u003c?php phpinfo(); ?\u003e\" \u003e ${application_path}/info.php\nif [ $(curl -s -G http://127.0.0.1/info.php | grep -q 'phpinfo' ; echo $?) == '0' ] ; then\necho \"PHP is working\" ; else\necho \"PHP is NOT working\" ; break ; fi\n#rm -f ${application_path}/info.php\n}\n```\n\n## 4. WP-CLI\n\nWP-CLI est un ensemble d’outils en ligne de commande pour gérer les installations WordPress. Vous pouvez mettre à jour les extensions, configurer des installations multi-site et beaucoup plus sans avoir recours à un navigateur web.\n\nVoir [WP-CLI: Interface en ligne de commande pour WordPress](https://wp-cli.org/fr/).\n\nToutes les opérations sur Wordpress en ligne de commande :\n\n* Téléchargement / mise à jour\n* Installation, configuration, création de base de données\n* Installation de thèmes, de plugins, création et gestion des utilisateurs\n* ...\n\n[Guide de démarrage wp-cli](https://make.wordpress.org/cli/handbook/quick-start/)\n\n[Installation wp-cli](https://make.wordpress.org/cli/handbook/installing/)\n\n### 4.1 Installation de wp-cli\n\n```bash\ncurl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar\nchmod +x wp-cli.phar ; mv wp-cli.phar /usr/local/bin/wp\n```\n\n### 4.2. Vérifier le fonctionnement de wp-cli\n\n```bash\n# Check if wp-cli is working\nif [ $(wp --info \u003e /dev/null ; echo $?) == '0' ] ; then\necho \"wp-cli is working\" ; else\necho \"wp-cli is NOT working\" ; fi\n```\n\n### 4.3. Télécharger Worpdress\n\n[wp core download](https://developer.wordpress.org/cli/commands/core/download/)\n\n```bash\n# Download Wordpress\nwp core download --path=${application_path} --locale=fr_FR\n```\n\n### 4.4. Création du fichier de configuration\n\n[wp config create](https://developer.wordpress.org/cli/commands/config/create/)\n\n```bash\n# Create wp-config.php\nwp config create --dbname=wp_database \\\n--dbuser=${dbuser} \\\n--dbpass=${dbuser_password} \\\n--path=${application_path}\n```\n\n### 4.4. Créer la base de données Wordpress\n\nLa base de données a été créée dans une étape précédente. Ici, pour documentation avec wp-cli.\n\n[wp db create](https://developer.wordpress.org/cli/commands/db/create/)\n\n### 4.6. Installation de Wordpress\n\n[wp core install](https://developer.wordpress.org/cli/commands/core/install/)\n\n```bash\n# Installation Wordpress\nwp core install --url=${site_url} \\\n--title=\"${site_title}\" \\\n--admin_user=${admin_user} \\\n--admin_password=${admin_password} \\\n--admin_email=${admin_email} \\\n--path=${application_path}\n```\n\n### 4.7. Mise-à-jour de tous les plugins dans leur dernière version\n\n```bash\n# Update plugins to their latest version\nwp plugin update --all --path=${application_path}\n```\n\n### 4.8. Affichage des informations\n\n```bash\necho \"Go to ${site_url} to access to your application\"\n```\n\n### 4.9. Résumé du déploiement de Wordpress\n\n```bash\nwpcli_installation() {\n# Installation de wp-cli\ncurl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar\nchmod +x wp-cli.phar ; mv wp-cli.phar /usr/local/bin/wp\n\n# Check if wp-cli is working\nif [ $(wp --info \u003e /dev/null ; echo $?) == '0' ] ; then\necho \"wp-cli is working\" ; else\necho \"wp-cli is NOT working\" ; fi\n}\n\nwordpress_installation() {\n# Download Wordpress\nwp core download --path=${application_path} --locale=fr_FR\n\n# Create wp-config.php\nwp config create --dbname=wp_database \\\n--dbuser=${dbuser} \\\n--dbpass=${dbuser_password} \\\n--path=${application_path}\n\n# Installation\nwp core install --url=${site_url} \\\n--title=\"${site_title}\" \\\n--admin_user=${admin_user} \\\n--admin_password=${admin_password} \\\n--admin_email=${admin_email} \\\n--path=${application_path}\n\n# Update plugins to their latest version\nwp plugin update --all --path=${application_path}\n}\n\nprint_end_message() {\n# Acces to your application\necho \"Go to ${site_url} to access to your application\"\n}\n```\n\n### 4.10. Programme principal\n\n```bash\nsoftware_installation\nenable_start_services\nopen_firewall\nstore_passwords\ntest_stack\nwordpress_database_creation\nmysql_secure\nwpcli_installation\nwordpress_installation\nprint_end_message\n\n```\n\n### 4.11. Améliorations et optimisations\n\n* Améliorer la gestion des erreurs\n* Configuration en Vhosts\n* Dépendance sendmail\n* HTTPS / Let's Encrypt\n* Renforcement sécuritaire de Wordpress\n* SELINUX\n\n## 5. Déploiement de la solution sur Centos 7 et Ubuntu\n\n[How to install Apache, PHP 7.2 and MySQL on CentOS 7.4 (LAMP)](https://www.howtoforge.com/tutorial/centos-lamp-server-apache-mysql-php/) et [How To Install Linux, Apache, MySQL, PHP (LAMP) stack on Ubuntu 16.04](https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-16-04).\n\nSur base de cette documentation sommaire, il est demandé d'adapter le script à la distribution Centos7 et Ubuntu.\n\n```\n[ $(grep -q 'Fedora release 27' /etc/fedora-release; echo $?) == 0 ]  \u0026\u0026 echo \"do someting on fedora\"\n[ -f /etc/centos-release ] \u0026\u0026 echo \"do someting on centos7\"\n[ -f /etc/lsb-release ] \u0026\u0026 echo \"do someting on ubuntu\"\n```\n\n### 5.1. Déploiement Centos7\n\nA peu de choses près, il s'agit s'utiliser la commande `yum` plutôt que `dnf`, sauf que `php-fpm` n'est pas installé par défaut.\n\n```bash\ncentos_software_installation() {\ncurl -L https://rpms.remirepo.net/enterprise/remi-release-7.rpm -o remi-release-7.rpm\nrpm -Uvh remi-release-7.rpm\nyum-config-manager --enable remi-php72\nyum -y install httpd mariadb-server php php-common php-mysqlnd php-gd php-imap php-xml php-cli php-opcache php-mbstring php-json firewalld\n}\n\ncentos_enable_start_services() {\nsystemctl enable httpd mariadb firewalld\nsystemctl start httpd mariadb firewalld\n}\n```\n\n[How to Install FastCGI PHP-FPM on CentOS 7](https://www.webhostinghero.com/blog/install-fastcgi-php-fpm-on-centos-7/)\n\n### 5.2. Déploiement sur Ubuntu\n\n```bash\nsudo apt update\nsudo -y apt install apache2 php libapache2-mod-php mariadb-server php-mysql php-curl php-gd php-intl php-json php-mbstring php-xml php-zip\nsudo systemctl enable apache2\nsudo systemctl enable mysql\nsudo systemctl start apache2\nsudo systemctl start mysql\n```\n\nVoici ce que cela donne dans le script.\n\n```bash\nubuntu_software_installation() {\nln -fs /usr/share/zoneinfo/Europe/Paris /etc/localtime\napt-get update\napt-get upgrade --yes --force-yes -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\"\napt -y install apache2 php libapache2-mod-php mariadb-server php-mysql php-curl php-gd php-intl php-json php-mbstring php-xml php-zip firewalld\n}\n\nubuntu_reload_services() {\n#systemctl enable apache2 mysql firewalld\nsystemctl reload apache2 mysql firewalld\nrm -rf /var/www/html/index.html\n}\n```\n\nLes options `--yes --force-yes -o Dpkg::Options::=\"--force-confdef\" -o Dpkg::Options::=\"--force-confold\"` de la commande `apt-get `\n\nPar défaut sous Ubuntu, les services installés sont activés et démarrent. Toutefois, il est nécessaire de redémarrer le service Apache.\n\nNotons aussi l'effacement de la page `index.html` associée au \"virtual host\" par défaut. En effet, dans cette configuration, en dehors de l'indiscrétion créée, elle entrera en concurrence avec la page `index.php` de Wordpress.\n\nEnfin, sous Ubuntu Bionic (18.04 LTS), configuration du paquet `tzdata` n'est pas nécessairement silencieuse de telle sorte que la zone horaire soit configurée d'avance (`ln -fs /usr/share/zoneinfo/Europe/Paris /etc/localtime`).\n\n### 5.2. Allow-root WP-CLI\n\nAussi, on remarquera que `wp-cli` n'autorise pas à priori une exécution en tant qu'utilisateur `root`, ce qui nous oblige à ajouter la directive `--allow-root` sur les commandes concernées.\n\n```bash\nwordpress_installation() {\n# Download Wordpress\nwp core download --path=${application_path} --locale=fr_FR --allow-root\n\n# Create wp-config.php\nwp config create --dbname=wp_database \\\n--dbuser=${dbuser} \\\n--dbpass=${dbuser_password} \\\n--path=${application_path} \\\n--allow-root\n\n# Installation\nwp core install --url=${site_url} \\\n--title=\"${site_title}\" \\\n--admin_user=${admin_user} \\\n--admin_password=${admin_password} \\\n--admin_email=${admin_email} \\\n--path=${application_path} \\\n--allow-root\n\n# Update plugins to their latest version\nwp plugin update --all --path=${application_path} --allow-root\n}\n\n```\n\n### 5.3. Appel aux fonctions selon la distribution\n\nQuel critère utiliser pour conditionner l'exécution des fonctions `fedora_*`, `centos_*` ou `ubuntu_*` ?\n\nChaque distribution dispose d'au moins un fichier qui identifie son origine :\n\n```bash\nif [ $(grep -q 'Fedora release 27' /etc/fedora-release; echo $?) == 0 ] ; then\nfedora_software_installation\nfedora_enable_start_services\nelif [ -f /etc/centos-release ] ; then\ncentos_software_installation\ncentos_enable_start_services\nelif [ -f /etc/lsb-release ] ; then\nubuntu_software_installation\nubuntu_enable_start_services\nfi\nopen_firewall\nwordpress_database_creation\nmysql_secure\nstore_passwords\ntest_stack\nwpcli_installation\nwordpress_installation\nprint_end_message\n```\n\nLa distribution Fedora évolue tous les six mois de telle sorte qu'il vaille mieux préciser sa version.\n\n## 6. Support HTTPS Let's Encrypt\n\n* Configuration Apache\n* Let's Encrypt Cert-Bot\n* Cron\n\n### 6.1. Virtual Hosts\n\n[Hôte virtuel](https://linux.goffinet.org/31_services_apache_http_server/#7-serveurs-virtuels-par-nom).\n\nIl serait de bonne pratique de configurer un \"virtual host\" supplémentaire (et de désactiver celui qui est installé par défaut).\n\n### 6.2. Fichier vhost pour Centos / Fedora\n\nVoici la procédure proposée pour Centos / Fedora.\n\n```bash\nfedora_vhost_creation() {\nport=\"80\"\nerror_log=\"/var/log/httpd/${site_name}-error_log\"\naccess_log=\"/var/log/httpd/${site_name}-access_log common\"\n#Résolution de nom locale\necho \"127.0.0.1 ${site_name}\" \u003e\u003e /etc/hosts\n#Création du dossier et des pages Web\nmkdir -p ${application_path}/${site_name}\n#Restauration de la policy Selinux sur le dossier créé\nrestorecon -Rv ${application_path}/${site_name}\n#Création du dossier et des fichiers pour les logs\nmkdir -p /var/log/httpd\ntouch /var/log/httpd/${site_name}-error_log\ntouch /var/log/httpd/${site_name}-access_log common\n#Configuration du vhost\ncat \u003c\u003c EOF \u003e /etc/httpd/conf.d/${site_name}.conf\n\u003cVirtualHost *:${port}\u003e\nServerAdmin webmaster@${site_name}\nDocumentRoot ${application_path}\nServerName ${site_name}\nErrorLog ${error_log}\nCustomLog ${access_log}\n\u003c/VirtualHost\u003e\nEOF\n}\n```\n\n```bash\nhttpd -D DUMP_VHOSTS\n```\n\n### 6.4. Fichier vhost pour Debian / Ubuntu\n\nIci, juste pour mémoire sur Ubuntu.\n\n`/etc/apache2/sites-available/example.com.conf`\n\n```apache\n\u003cVirtualHost *:80\u003e\n\tServerName example.com\n\tServerAlias www.example.com\n\tDocumentRoot \"/var/www/example\"\n\t\u003cDirectory \"/var/www/example\"\u003e\n\t\tOptions FollowSymLinks\n\t\tAllowOverride all\n\t\tRequire all granted\n\t\u003c/Directory\u003e\n\tErrorLog /var/log/apache2/error.example.com.log\n\tCustomLog /var/log/apache2/access.example.com.log combined\n\u003c/VirtualHost\u003e\n```\n\nEn Debian / Ubuntu, une configuration `000-default` est présentez dans le répertoire `/etc/apache2/sites-available`. Aussi, le script `a2ensite` active un hôte virtuel et le script `a2dissite` en désactive un avec le nom du fichier de configuration en paramètre.\n\n```bash\nsudo a2ensite example.com.conf\nsudo a2dissite 000-default\nsudo systemctl reload apache2\n```\n\n### 6.5. Mise en commun de la configuration vhost\n\n```bash\nvhost_creation() {\nport=\"80\"\nerror_log=\"${log_path}/${site_name}-error_log\"\naccess_log=\"${log_path}/${site_name}-access_log common\"\n#Résolution de nom locale\necho \"127.0.0.1 ${site_name}\" \u003e\u003e /etc/hosts\n#Création du dossier et des pages Web\nmkdir -p ${application_path}/${site_name}\n#Création du dossier et des fichiers pour les logs\nmkdir -p ${log_path}\ntouch ${error_log}\ntouch ${access_log}\n#Configuration du vhost\ncat \u003c\u003c EOF \u003e ${vhost_path}/${site_name}.conf\n\u003cVirtualHost *:${port}\u003e\nServerAdmin webmaster@${site_name}\nDocumentRoot ${application_path}\nServerName ${site_name}\nErrorLog ${error_log}\nCustomLog ${access_log}\n\u003c/VirtualHost\u003e\nEOF\n}\n```\n\n```bash\nif  $(grep -q 'Fedora release 27' /etc/fedora-release; echo $?) == 0 ] ; then\nfedora_software_installation\nelif [ -f /etc/centos-release ] ; then\ncentos_software_installation\nelif [ -f /etc/lsb-release ] ; then\nubuntu_software_installation\nopen_firewall\nlog_path=\"/var/log/apache2\"\nvhost_path=\"/etc/apache2/sites-available\"\nvhost_creation\na2dissite 000-default ; a2ensite ${site_name}.conf\nubuntu_reload_services\nfi\nif [ -f /etc/redhat-release ] ; then\nopen_firewall\nlog_path=\"/var/log/httpd\"\nvhost_path=\"/etc/httpd/conf.d\"\nvhost_creation\n#Restauration de la policy Selinux sur le dossier créé\nrestorecon -Rv ${location}/${host}\ncentos_enable_start_services\nfi\n```\n\n### 6.6. Certbot Let's Encrypt\n\nL'utilitaire certbot permet de générer des certificats TLS valides automatiquement à condition qu'un **enregistrement DNS public** corresponde au site Web et qu'un **service HTTP** soit activé. Chaque distribution installe son paquet :\n\nSous Fedora :\n\n```bash\ndnf install certbot-apache\n```\n\nSous Centos 7 :\n\n```bash\nyum install python2-certbot-apache\n```\n\nSous Debian / Ubuntu :\n\n```bash\nsudo apt-get update\nsudo apt-get install software-properties-common\nsudo add-apt-repository ppa:certbot/certbot\nsudo apt-get update\nsudo apt-get install python-certbot-apache\n```\n\nUne fonction dans le script pourrait ressembler à ceci :\n\n```\nhttps_installation() {\nsystemctl reload httpd || systemctl reload apache2\nchown apache:apache /run/php-fpm/www.sock 2\u003e /dev/null\n# Three times if DNS failure\ncertbot --apache --register-unsafely-without-email --agree-tos -d \"${site_name}\" -n || \\\ncertbot --apache --register-unsafely-without-email --agree-tos -d \"${site_name}\" -n || \\\ncertbot --apache --register-unsafely-without-email --agree-tos -d \"${site_name}\" -n\n(crontab -l 2\u003e/dev/null; echo \"0 0,12 * * * python -c \"import random; import time; time.sleep(random.random() * 3600)\" \u0026\u0026 certbot renew\") | crontab -\n}\n```\n\nVoici le résultat de l'opération :\n\n```bash\ncat /etc/httpd/conf.d/www.51.158.65.218.nip.io-le-ssl.conf\n\u003cIfModule mod_ssl.c\u003e\n\u003cVirtualHost *:443\u003e\nServerAdmin webmaster@www.51.158.65.218.nip.io\nDocumentRoot /var/www/html\nServerName www.51.158.65.218.nip.io\nErrorLog /var/log/httpd/www.51.158.65.218.nip.io-error_log\nCustomLog /var/log/httpd/www.51.158.65.218.nip.io-access_log common\n\nSSLCertificateFile /etc/letsencrypt/live/www.51.158.65.218.nip.io/fullchain.pem\nSSLCertificateKeyFile /etc/letsencrypt/live/www.51.158.65.218.nip.io/privkey.pem\nInclude /etc/letsencrypt/options-ssl-apache.conf\n\u003c/VirtualHost\u003e\n\u003c/IfModule\u003e\n```\n\n## 7. Déploiement Wordpress Haute Disponiblité (IaaS)\n\nInspiré de [Ansible playbooks to install Wordpress in a HA configuration on IBM Cloud IaaS](https://github.com/stevestrutt/wordpress_ansible_ibmcloud)\n\n![Single site deployment, using 3 Centos 7.x VSIs and a Cloud Load Balancer](https://developer.ibm.com/recipes/wp-content/uploads/sites/41/2018/08/WordpressCLB.png)\n\n[Single site deployment, using 3 Centos 7.x VSIs and a Cloud Load Balancer](https://developer.ibm.com/recipes/tutorials/high-availability-deployment-of-wordpress-using-ansible/)\n\n![Dual site deployment](https://developer.ibm.com/recipes/wp-content/uploads/sites/41/2018/08/WordpressGLB.png)\n\n[Dual site deployment](https://developer.ibm.com/recipes/tutorials/high-availability-deployment-of-wordpress-using-ansible/)\n\n## 8. Déploiement sur Docker\n\nStack LAMP/Wordpress sur Docker.\n\n[Docker pour ma stack LAMP](https://blog.kulakowski.fr/post/docker-pour-ma-stack-lamp)\n\n![Schéma d’architecture simplifié de la stack LAMP sous Docker](https://blog.kulakowski.fr/wp-content/uploads/2018/04/architecture_docker_light.png)\n\n![Schéma d’architecture complet de la stack LAMP sous Docker](https://blog.kulakowski.fr/wp-content/uploads/2018/04/architecture_docker-768x724.png)\n\nArchitecture Docker Compose\n\n```yaml\nversion: '2.1'\n\n# All services\nservices:\n  httpd:\n    container_name: httpd\n    image: llaumgui/httpd24\n    build:\n      context: build/httpd/2.4/\n    restart: always\n    volumes:\n     - /etc/localtime:/etc/localtime:ro\n     - /docker/volumes/www:/var/www/\n     - /docker/conf/httpd/vhost.d:/usr/local/apache2/conf/vhost.d:ro\n     - /docker/conf/httpd/ssl:/usr/local/apache2/ssl:ro\n    ports:\n     - \"80:80\"\n     - \"443:443\"\n\n  php:\n    container_name: php\n    image: llaumgui/php:7.2-fpm\n    build:\n      context: build/php-fpm/7.2/\n      args:\n        DOCKER_PHP_ENABLE_APCU: 'on'\n        DOCKER_PHP_ENABLE_COMPOSER: 'on'\n        DOCKER_PHP_ENABLE_LDAP: 'off'\n        DOCKER_PHP_ENABLE_MEMCACHED: 'off'\n        DOCKER_PHP_ENABLE_MONGODB: 'off'\n        DOCKER_PHP_ENABLE_MYSQL: 'on'\n        DOCKER_PHP_ENABLE_POSTGRESQL: 'off'\n        DOCKER_PHP_ENABLE_REDIS: 'on'\n        DOCKER_PHP_ENABLE_SYMFONY: 'off'\n        DOCKER_PHP_ENABLE_XDEBUG: 'off'\n        DOCKER_USER_UID: 1001\n        DOCKER_USER_GID: 1001\n    restart: always\n    volumes:\n     - /etc/localtime:/etc/localtime:ro\n     - /docker/volumes/www:/var/www/\n    expose:\n     - 9000\n    ports:\n     - \"127.0.0.1:9000:9000\"\n    depends_on:\n     - httpd\n     - mariadb\n     - redis\n    links:\n     - mariadb:database\n    extra_hosts:\n     - \"mailserver:172.18.0.1\"\n\n  mariadb:\n    container_name: mariadb\n    image: mariadb:10.1\n    restart: always\n    env_file:\n     - /docker/conf/mariadb.env\n    volumes:\n     - /etc/localtime:/etc/localtime:ro\n     - /docker/volumes/mariadb:/var/lib/mysql\n     - /docker/volumes/mysqldump:/mysqldump\n    expose:\n     - 3306\n    ports:\n     - \"127.0.0.1:3306:3306\"\n\n  redis:\n    container_name: redis\n    image: redis:4-alpine\n    restart: always\n    volumes:\n     - /etc/localtime:/etc/localtime:ro\n    expose:\n     - 6379\n```\n\n## 9. Approvisionnement Ansible\n\nStack LAMP/wordpress à partir d'Ansible. A documenter. Voir plus haut.\n\n## 10. Application Stateful Wordpress sur un cluster Kubernetes\n\nA documenter.\n\n[GCP Click-to-deploy Wordpress](https://github.com/GoogleCloudPlatform/click-to-deploy/tree/master/k8s/wordpress)\n\n## 11. Script Bash final\n\n```bash\n#!/bin/bash\n\nip_address=$(curl -s https://ipinfo.io/ip)\nsite_title=\"Demo Wordpress\"\nsite_url=\"www.${ip_address}.nip.io\"\napplication_path=\"/var/www/html\"\nadmin_email=\"test@test.com\"\nadmin_user=\"admin\"\nadmin_password=$(openssl rand -base64 12)\ndbuser=\"wpuser\"\ndbroot_password=$(openssl rand -base64 12)\ndbuser_password=$(openssl rand -base64 12)\n\nsoftware_installation() {\nif [ $(grep -q 'Fedora release 27' /etc/fedora-release; echo $?) == 0 ] ; then\ndnf -y install httpd mariadb-server php php-common php-mysqlnd php-gd php-imap php-xml php-cli php-opcache php-mbstring php-json\nsed -i 's/^listen.acl_users/;listen.acl_users/g' /etc/php-fpm.d/www.conf\nelif [ -f /etc/centos-release ] ; then\ncurl -L https://rpms.remirepo.net/enterprise/remi-release-7.rpm -o remi-release-7.rpm\nrpm -Uvh remi-release-7.rpm\nyum-config-manager --enable remi-php72\nyum -y install httpd mariadb-server php php-common php-mysqlnd php-gd php-imap php-xml php-cli php-opcache php-mbstring php-json firewalld\necho \"PHP Version: $(php -v)\"\nelif [ -f /etc/lsb-release ] ; then\nln -fs /usr/share/zoneinfo/Europe/Paris /etc/localtime\napt-get update\nDEBIAN_FRONTEND=noninteractive DEBIAN_PRIORITY=critical \\\napt-get -q -y -o \"Dpkg::Options::=--force-confdef\" -o \"Dpkg::Options::=--force-confold\" upgrade\napt -y install apache2 php libapache2-mod-php mariadb-server php-mysql php-curl php-gd php-intl php-json php-mbstring php-xml php-zip firewalld\nelse\nbreak\nfi\n}\n\nvhost_creation() {\nport=\"80\"\nerror_log=\"${log_path}/${site_url}-error_log\"\naccess_log=\"${log_path}/${site_url}-access_log common\"\n#Résolution de nom locale\necho \"127.0.0.1 ${site_url}\" \u003e\u003e /etc/hosts\n#Création du dossier et des pages Web\nmkdir -p ${application_path}\n#Création du dossier et des fichiers pour les logs\nmkdir -p ${log_path}\ntouch ${error_log}\ntouch ${access_log}\n#Configuration du vhost\ncat \u003c\u003c EOF \u003e ${vhost_path}/${site_url}.conf\n\u003cVirtualHost *:${port}\u003e\nServerAdmin webmaster@${site_url}\nDocumentRoot ${application_path}\nServerName ${site_url}\nErrorLog ${error_log}\nCustomLog ${access_log}\n\u003c/VirtualHost\u003e\nEOF\n}\n\nvhosts_installation() {\nif [ -f /etc/redhat-release ] ; then\nlog_path=\"/var/log/httpd\"\nvhost_path=\"/etc/httpd/conf.d\"\nvhost_creation\n#Restauration de la policy Selinux sur le dossier créé\nrestorecon -Rv ${application_path}\nelif [ -f /etc/lsb-release ] ; then\nlog_path=\"/var/log/apache2\"\nvhost_path=\"/etc/apache2/sites-available\"\nvhost_creation\na2dissite 000-default ; a2ensite ${site_url}.conf\nfi\n}\n\nenable_start_services() {\nif  $(grep -q 'Fedora release 27' /etc/fedora-release; echo $?) == 0 ] ; then\nsystemctl enable httpd mariadb php-fpm firewalld\nsystemctl start httpd mariadb php-fpm firewalld\nchown apache:apache /run/php-fpm/www.sock\nelif [ -f /etc/centos-release ] ; then\nsystemctl enable httpd mariadb firewalld\nsystemctl start httpd mariadb firewalld\nelif [ -f /etc/lsb-release ] ; then\nsystemctl enable apache2 mysql firewalld\nsystemctl start apache2 mysql\nsystemctl start firewalld\nsystemctl reload apache2 mysql firewalld\nrm -rf /var/www/html/index.html\nelse\nbreak\nfi\n}\n\nopen_firewall() {\nfirewall-cmd --zone=public --add-service=http --permanent\nfirewall-cmd --zone=public --add-service=https --permanent\nfirewall-cmd --reload\n}\n\nhttps_activation() {\n# Three times if DNS failure\ncertbot --apache --register-unsafely-without-email --agree-tos -d \"${site_url}\" -n || \\\ncertbot --apache --register-unsafely-without-email --agree-tos -d \"${site_url}\" -n || \\\ncertbot --apache --register-unsafely-without-email --agree-tos -d \"${site_url}\" -n\n#(crontab -l 2\u003e/dev/null; echo \"0 0,12 * * * python -c \"import random; import time; time.sleep(random.random() * 3600)\" \u0026\u0026 certbot renew\") | crontab -\n}\n\nhttps_installation() {\nif  $(grep -q 'Fedora release 27' /etc/fedora-release; echo $?) == 0 ] ; then\ndnf -y install certbot-apache\nmv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.old\nhttps_activation\nsystemctl reload httpd\nchown apache:apache /run/php-fpm/www.sock\nelif [ -f /etc/centos-release ] ; then\nyum -y install python2-certbot-apache\nmv /etc/httpd/conf.d/ssl.conf /etc/httpd/conf.d/ssl.conf.old\nhttps_activation\nsystemctl reload httpd\nelif [ -f /etc/lsb-release ] ; then\napt-get update\napt-get -y install software-properties-common\nadd-apt-repository ppa:certbot/certbot -y\napt-get -y update\napt-get -y install python-certbot-apache\nhttps_activation\nsystemctl reload apache2\nelse\nbreak\nfi\n}\n\nmysql_secure() {\nmysql -e \"UPDATE mysql.user SET Password = PASSWORD('${dbroot_password}') WHERE User = 'root'\"\nmysql -e \"DROP USER ''@'localhost'\"\nmysql -e \"DROP USER ''@'$(hostname)'\"\nmysql -e \"DROP DATABASE test\"\nmysql -e \"FLUSH PRIVILEGES\"\n}\n\nwordpress_database_creation() {\nmysql -e \"CREATE USER ${dbuser}@localhost IDENTIFIED BY '${dbuser_password}'\"\nmysql -e \"CREATE DATABASE wp_database\"\nmysql -e \"GRANT ALL ON wp_database.* TO ${dbuser}@localhost\"\nmysql -e \"FLUSH PRIVILEGES\"\n}\n\nstore_passwords() {\necho \"DBROOT_PASSWORD=\\\"${dbroot_password}\\\"\" \u003e ~/.pw_wordpress\necho \"DBUSER_PASSWORD=\\\"${dbuser_password}\\\"\" \u003e\u003e ~/.pw_wordpress\necho \"ADMIN_PASSWORD=\\\"${admin_password}\\\"\" \u003e\u003e ~/.pw_wordpress\nchmod 600 ~/.pw_wordpress\n}\n\ntest_stack() {\n# Test Apache\nif [ $(curl -s -I 127.0.0.1 | grep -q 'Server: Apache' ; echo $?) == '0' ] ; then\necho \"Apache is working\" ; else\necho \"Apache is NOT working\" ; fi\n# Test PHP\necho \"\u003c?php phpinfo(); ?\u003e\" \u003e /var/www/html/info.php\nif [ $(curl -s -G http://127.0.0.1/info.php | grep -q 'phpinfo' ; echo $?) == '0' ] ; then\necho \"PHP is working\" ; else\necho \"PHP is NOT working\" ; fi\nrm -f /var/www/html/info.php\n}\n\nwpcli_installation() {\n# Installation de wp-cli\ncurl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar\nchmod +x wp-cli.phar ; mv wp-cli.phar /usr/local/bin/wp\n\n# Check if wp-cli is working\nif [ $(/usr/local/bin/wp --info \u003e /dev/null ; echo $?) == '0' ] ; then\necho \"wp-cli is working\" ; else\necho \"wp-cli is NOT working\" ; fi\n}\n\nwordpress_installation() {\n# Download Wordpress\n/usr/local/bin/wp core download --path=${application_path} --locale=fr_FR --allow-root\n\n# Create wp-config.php\n/usr/local/bin/wp config create --dbname=wp_database \\\n--dbuser=${dbuser} \\\n--dbpass=${dbuser_password} \\\n--path=${application_path} \\\n--allow-root\n\n# Installation\n/usr/local/bin/wp core install --url=${site_url} \\\n--title=\"${site_title}\" \\\n--admin_user=${admin_user} \\\n--admin_password=${admin_password} \\\n--admin_email=${admin_email} \\\n--path=${application_path} \\\n--allow-root\n\n# Update plugins to their latest version\n/usr/local/bin/wp plugin update --all --path=${application_path} --allow-root\n}\n\nprint_end_message() {\n# Acces to your application\necho \"Go to http://${site_url} or https://${site_url} to access to your application\" | tee /root/wordpress_url.txt\n}\n\n\nsoftware_installation\nvhosts_installation\nenable_start_services\nopen_firewall\nhttps_installation\nwordpress_database_creation\nmysql_secure\nstore_passwords\ntest_stack\nwpcli_installation\nwordpress_installation\nprint_end_message\n\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoffinet%2Flab-automation-wordpress","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoffinet%2Flab-automation-wordpress","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoffinet%2Flab-automation-wordpress/lists"}