Sur Orion, j’ai installé ma WordPress Rocket Stack qui est configurée avec la stack suivante:
- Ubuntu Server 22.04 LTS
- MySQL 8+
- NginX 1.25+
- PHP 8.3
- Redis
- Nginx FastCGI Cache
- Fail2ban
- LetsEncrypt avec acme.sh
Hébergement
L’hébergement est la base de votre site, c’est tout simplement la fondation sur laquelle va reposer votre code.
Vous avez tout intérêt à avoir un très bon hébergeur : il doit être rapide dès le départ et offrir de bonnes garanties en termes de performance et de sécurité.
Si vous avez un site WordPress ou WooCommerce, je ne peux que vous recommander Kinsta, WPEngine ou Nexcess. Tous trois sont de très bons hébergeurs, particulièrement orientés vers la performance avec des ressources garanties et un support technique réactif et efficace en cas de besoin.
Personnellement, j’utilise un serveur dédié chez OVH parce que j’héberge pas mal de sites et j’ai besoin d’avoir un contrôle fin sur la configuration de chacun des services.
Ubuntu Server
J’étais auparavant sous Debian mais j’ai finalement opté pour Ubuntu Server 22.04 LTS pour ce nouveau serveur.
L’avantage d’Ubuntu est de pouvoir disposer des mises à jour plus rapidement que sous Debian.
Installation de la WordPress Rocket Stack
# MySQL
# Latest link is always on the apt page: https://dev.mysql.com/downloads/repo/apt/
wget -c https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb
dpkg -i mysql-apt-config_0.8.29-1_all.deb
# Packages
apt install software-properties-common tmux curl wget zip unzip git
add-apt-repository ppa:ondrej/php
add-apt-repository ppa:ondrej/nginx-mainline
apt update -y
apt upgrade -y
apt install mysql-server -y # accept all defaults
# PHP 8.3
# Note: the json module is now part of PHP core
apt install php8.3 php8.3-apcu php8.3-bcmath php8.3-bz2 php8.3-cli php8.3-common php8.3-curl php8.3-fpm php8.3-gd php8.3-gmp php8.3-igbinary php8.3-imagick php8.3-imap php8.3-intl php8.3-mbstring php8.3-mysql php8.3-opcache php8.3-phpdbg php8.3-readline php8.3-redis php8.3-soap php8.3-xml php8.3-zip -y
# Run installs
apt install nginx -y
apt install fail2ban -y
apt install redis -y
apt install libnginx-mod-http-brotli-filter libnginx-mod-http-brotli-static -y
# Get NginX config files
git clone https://github.com/skyminds/wordpress-rocketstack
cp wordpress-rocketstack/nginx/* /etc/nginx/ -R
rm wordpress-rocketstack
Code language: PHP (php)
DNS : ajout du site sur le serveur
Mon serveur est hébergé chez OVH donc il faut ajouter le domaine aux DNS secondaires du serveur.
Sur l’interface Kimsufi, cela se fait très simplement:
Configurer Cloudflare
Si vous utilisez Cloudflare – ce que je vous recommande fortement – et que vous obtenez une erreur 403 ou alors une page “Welcome to NginX” en lieu et place de votre nouveau site, veillez bien à sélectionner la bonne option SSL dans Cloudflare > Example.com > SSL/TLS > Overview : il faut sélectionner Full ou Full (Strict) mais surtout pas “Flexible“:
Ensuite, il ne nous reste qu’à faire pointer le CNAME vers l’adresse IP du serveur et d’ajouter le champs TXT qui a été indiqué par OVH dans l’étape précédente:
Ajout du server block NginX
DOMAIN="example.com"
DOMAINDIR="example"
mkdir -p /home/www/$DOMAINDIR
chown www-data:www-data /home/www/$DOMAINDIR
mkdir -p /home/nginx-cache/$DOMAINDIR
chown -R www-data:www-data /home/nginx-cache/
cp /etc/nginx/sites-available/wprocketstack.conf /etc/nginx/sites-available/$DOMAINDIR.conf
rm /etc/nginx/sites-enabled/default
rm /etc/nginx/sites-available/default
Code language: PHP (php)
On édite ensuite la configuration:
nano /etc/nginx/sites-available/$DOMAINDIR.conf
Code language: PHP (php)
Mettez l’adresse du site dans la directive server_name
:
server_name example.com
Code language: CSS (css)
Installation du certificat SSL avec acme.sh
curl https://get.acme.sh | sh
Code language: JavaScript (javascript)
Quittez votre session SSH puis rouvrez la session SSH, vérifiez qu’acme.sh
est bien installé:
acme.sh -h
Code language: CSS (css)
On peut créer un certificat avec acme.sh
de différentes manières.
Personnellement, j’aime bien la procédure qui ajoute un enregistrement DNS au domaine pour vérifier que vous en êtes bien le propriétaire.
Trouvez votre hébergeur dans la liste. Ici un exemple avec GoDaddy:
export GD_Key="W7N7hKxHk99kr7ubx"
export GD_Secret="WUbD5ejrsxBe52"
acme.sh --issue -d $DOMAIN -d *.$DOMAIN --keylength ec-384 --dns dns_gd
Code language: JavaScript (javascript)
J’utilise CloudFlare donc j’ajoute mes identifiants au fichier .bashrc:
nano .bashrc
export CF_Key="1111111111111111111111111"
export CF_Email="user@example.com"
Code language: JavaScript (javascript)
On lance ensuite la demande de certificat wildcard pour le domaine:
acme.sh --issue -d $DOMAIN -d *.$DOMAIN --keylength ec-384 --dns dns_cf
Code language: PHP (php)
On déplace ensuite les fichiers de notre nouveau certificat dans un répertoire de la configuration nginx
, pour rassembler toute notre configuration au même endroit:
mkdir -p /etc/nginx/ssl/$DOMAIN
acme.sh --install-cert --ecc -d $DOMAIN --key-file /etc/nginx/ssl/$DOMAIN/privkey.pem --fullchain-file /etc/nginx/ssl/$DOMAIN/fullchain.pem --reloadcmd "service nginx force-reload"
Code language: PHP (php)
Le certificat SSL est automatiquement régénéré tous les 60 jours, automatiquement via un cronjob.
Il vous reste à éditer la configuration de votre server block SSL dans votre fichier de configuration nginx pour ajouter les références aux fichiers du certificat:
server{
# ...
# acme.sh cert
ssl_certificate /etc/nginx/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/example.com/privkey.pem;
# ...
}
Code language: PHP (php)
On vérifie la configuration :
nginx -t
Et on peut désormais activer notre bloc serveur :
ln -s /etc/nginx/sites-available/$DOMAINDIR.conf /etc/nginx/sites-enabled/
Code language: PHP (php)
Et on relance nginx :
service nginx restart
Configuration du firewall
Nous sommes sous Ubuntu donc UFW est déjà installé mais n’est pas activé :
ufw status verbose
Status: inactive
Première chose à faire, lister les applications détectées par UFW :
ufw app list
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
Code language: PHP (php)
Deuxième chose extrêmement importante à faire : autoriser la connexion SSH, autrement lorsque le firewall sera activé, on ne pourra plus joindre le serveur :
ufw allow ssh
ufw allow 'Nginx Full'
ufw allow from XXX.XXX.XXX.XXX
Code language: JavaScript (javascript)
Par précaution, ajoutez aussi votre IP, on ne sait jamais. On active ensuite le pare-feu :
ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
Code language: JavaScript (javascript)
Configuration de MySQL
On commence par sécuriser notre installation de MySQL :
mysql_secure_installation
Vous pouvez répondre Y à toutes les questions pour tout bétonner.
On passe ensuite à la création de notre base de données et utilisateur SQL :
mysql -u root -p
[MOT DE PASSE ROOT]
Code language: CSS (css)
Une fois dans la console MySQL :
CREATE DATABASE example;
CREATE USER 'example-USER'@'localhost' IDENTIFIED BY '1nyXI7Y)$spmslgz4HhdE4Lc_vm&)Gh!MsZFk';
GRANT ALL PRIVILEGES ON example.* TO 'example-USER'@'localhost';
FLUSH PRIVILEGES;
EXIT;
Code language: PHP (php)
On optimise un peu notre instance MySQL :
nano /etc/mysql/mysql.conf.d/mysqld.cnf
Et on ajoute à la fin du fichier :
innodb_buffer_pool_size = 200M
innodb_log_file_size = 100M
innodb_buffer_pool_instances = 8
innodb_io_capacity = 5000
max_binlog_size = 100M
expire_logs_days = 3
On redémarre ensuite le serveur MySQL :
service mysql restart
Configuration de PHP
On édite le fichier de configuration de PHP-FPM:
# PHP 8.3
nano /etc/php/8.3/fpm/php.ini
Code language: PHP (php)
Et on modifie les directives suivantes :
max_execution_time = 6000
max_input_vars = 6000
memory_limit = 512M
upload_max_filesize = 100M
post_max_size = 100M
opcache.enable=1
opcache.memory_consumption=1024
opcache.interned_strings_buffer=64
opcache.max_accelerated_files=50000
opcache.revalidate_freq=60
On édite ensuite notre pool PHP :
# PHP 8.3
nano /etc/php/8.3/fpm/pool.d/www.conf
Code language: PHP (php)
Avec la configuration suivante :
pm = dynamic
pm.max_children = 120
pm.start_servers = 20
pm.min_spare_servers = 10
pm.max_spare_servers = 30
; MATT : SECURITY
php_admin_value[disable_functions] = passthru,shell_exec,system
; MATT : NEXTCLOUD
clear_env = no
On enregistre le fichier et on redémarre PHP :
# PHP 8.3
service php8.3-fpm restart
Code language: CSS (css)
Installation de WordPress avec wp-cli
On peut maintenant installer wp-cli
pour gérer WordPress :
wget https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp
# update
wp cli update
Code language: PHP (php)
Et lancer l’installation de WordPress :
# DB connection details used for WP install
DB="example"
DBUSER="example-USER"
DBPASSWORD="1nyXI7Y)$spmslgz4HhdE4Lc_vm&)Gh!MsZFk"
cd /home/www/$DOMAINDIR
wp core download --allow-root
chown www-data:www-data * -R
wp core config --dbhost=localhost --dbname=$DB --dbuser=DBUSER --dbpass=$DBPASSWORD --allow-root
chmod 600 wp-config.php
# WP admin user
WPADMINPASSWORD="CzHCI&uBoyRJuIVHLdTg_Sn9RtV$w#B8G51KYn$o@o8q78ANu-GpU7iDg9nlRRq"
WPADMINEMAIL="root@example.com"
wp core install --url="https://${SITEURL}" --title="Rocket Stack" --admin_name=$DB-admin --admin_password=$WPADMINPASSWORD --admin_email=$WPADMINEMAIL --allow-root
chown www-data:www-data /home/www/$DOMAINDIR -R
Code language: PHP (php)
Configuration de Redis
Le serveur dispose de 32 Go de RAM, on alloue donc 3 Go pour redis
:
echo "maxmemory 3000mb" >> /etc/redis/redis.conf
echo "maxmemory-policy allkeys-lru" >> /etc/redis/redis.conf
sed -i 's/^save /#save /gi' /etc/redis/redis.conf
Code language: JavaScript (javascript)
Et on redémarre le service :
service redis-server restart
Ensuite, il vous suffit d’installer le plugin Redis Object Cache de Till Krüss, et d’activer le cache Redis dans les options du plugin pour servir le site directement depuis les objets mis en cache mémoire par Redis.
Conclusion
Et voilà, vous devriez avoir tout ce qu’il faut pour avoir une très bonne base pour lancer votre site WordPress sur votre propre serveur dédié ou VPS.
Vous voulez un site WordPress ou WooCommerce qui soit à la fois rapide et performant? Vous êtes au bon endroit.