¡Seguimos la serie de servidores! Esta vez me voy a adentrar en algo que se me escapa un poco… no conozco muy bien ni ElasticSeach ni Redis, pero quiero tener un servidor con todo lo que Adobe (Magento) nos recomienda y requiere para que funcione:
- Servido web Nginx/Apache: usaremos Nginx
- PHP
- MySQL
- Composer
- ElasticSearch
- Redis (no es obligatorio pero digamos que sin Redis las caches no son lo mismo…)
NOTA tras acabar el post -> Y para no mentir, entre que voy de a ratitos, tuve que investigar algo tan sencillo como «cómo instalar una versión concreta de Redis», etc… esto me ha llevado la vida jeje pero lo he acabado con mucho gusto la verdad. He de decirlo también, me esperaba que fuera algo más sencillo… pero oye, había que hacerlo, no puedo estar trabajando con Magento y no tener ni idea de la configuración del servidor que lo sostiene no?
¿De qué punto partimos?
Tengo mi VPS de pruebas con Nginx, PHP (phpfpm) v8.1 qeu ya veremos si me toca hacer un downgrade, MySQL v8.0 que también ya veremos si me toca hacer otro downgrade.
Me falta instalar Composer, ElasticSearch y Redis… y no sé si necesitaré aprender algo básico antes de poder realizar las configuraciones pertinentes.
Vamos a confiar en la documentación de Magento para guiarnos en todo el proceso (crucemos los dedos).
Requerimientos Magento versión actual
La versión en el momento de probar y escribir esto es Magento v2.4.5. Y los requerimientos son (https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/system-requirements.html?lang=en):
- PHP v8.1
- Composer v2.2
- Nginx v1.18
- MySQL 8.0 (MariaDB 10.4)
- ElasticSearch v7.17 (OpenSearch v 1.2)
- Redis v6.2
PHP
Bueno… no me hace falta downgrade. La 8.1 está ok. Pero me faltan un montón de extensiones listadas en https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/prerequisites/php-settings.html?lang=en y seguiremos luego con el resto de pasos
Extensiones
Para comprobar las extensiones
php -m
Las extensiones se instalan con (siendo mi versión de PHP la 8.1):
apt install php8.1-[extension-name]
Así que instalo todas las que me faltan de la lista del link de antes con el comando:
apt install php8.1-bcmath php8.1-ctype php8.1-curl php8.1-dom php8.1-gd php8.1-intl php8.1-mbstring php8.1-simplexml php8.1-soap php8.1-xmlwriter php8.1-xsl php8.1-zip
(creo que hay una forma de instalar PHP con estos módulos también, pero no me voy a meter ahora en probarlo…)
Cambios en el php.ini, que saco la ruta haciendo un phpinfo(). No hagas un php –ini | grep «Loaded Configuration File» porque te dará la versión del CLI y nosotros estamos usando phpfpm… no serán iguales y te dará una ruta para configurar php en el CLI.
vim /etc/php/8.1/fpm/php.ini
# buscamos, descomentamos y dejamos estas líneas así
date.timezone = Europe/Madrid
memory_limit = 1G
realpath_cache_size=10M y realpath_cache_ttl=7200
opcache.save_comments=1
max_execution_time = 1800
zlib.output_compression = On
Finalmente reiniciamos Nginx para que surta todo efecto:
service nginx restart
MySQL
Tenemos este link https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/prerequisites/database-server/mysql.html?lang=en
Habilitar el modo STRICT_ALL_TABLES SQL y el row based replication:
mysql> SET sql_mode = 'STRICT_ALL_TABLES';
mysql> SET GLOBAL binlog_format = 'ROW';
Aumentar: max_allowed_packet, tmp_table_size, max_heap_table_size y innodb_buffer_pool_size
NOTA: la documentación no aclara a cuánto subirlo
# vim /etc/mysql/mysql.conf.d/mysql.cnf
max_allowed_packet = 512M
tmp_table_size = 64M
max_heap_table_size = 64M
innodb_buffer_pool_size = 2147483648
Crear base de datos para magento y su usuario:
create database magento;
create user 'magento'@'localhost' IDENTIFIED BY 'magento';
GRANT ALL ON magento.* TO 'magento'@'localhost';
flush privileges;
Por tanto deberíamos ahora poder acceder a las bases de datos desde
mysql -u magento -p
Nginx
En otra entrada (ésta de aquí) analizo e intento (aclaro… intento jeje) entender desde mi escaso conocimiento de estos temas, qué hace y como se configura un Nginx correctamente para Magento 2, así que muchas cosas me remito a esa sección de esa entrada.
Para nginx tenemos esta página https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/prerequisites/web-server/nginx.html?lang=en.
Lo primero que nos recomiendan es seguir el fichero de configuración de ejemplo que nos trae Magento en su raíz, el nginx.conf.sample. Hay que crear un nuevo virtual host con el contenido que indican. Y ello hace:
- utiliza un upstream para conectarse al socket de phpfpm (esto va fuera del bloque server, porque debe ir dentro del bloque http de Nginx)
- dentro del bloque server principal, 2 cosas
- define la variable $MAGE_ROOT a lo que sería el root de virtual host
- como explico en el post que comento más arriba, en el include hace root $MAGE_ROOT/pub; definiendo que el document root de la aplicación sea pub
- toda el resto de la configuración va con un include al nginx.conf.sample de la raíz de la instalación que me remito al post anterior (éste de aquí)
- define la variable $MAGE_ROOT a lo que sería el root de virtual host
- Yo ya tenía instalado con Certbot un SSL, así que esa parte no la he quitado (ni las líneas que hacen referencia a la configuración de los archivos del certificado en el servidor, ni el bloque server adicional que hace la redirección de todo el tráfico del puerto 80 al 443, así que al final los pasos fueron:
- poner antes del bloque server principal el bloque upstream
- borrar el contenido del bloque server principal a excepción de lo relacionado con el SSL metido por Certbot
- poner las líneas que indica magento (server_name, set $MAGE_ROOT, el include al nginx.conf.sample)
Motor de búsquedas (ElasticSearch)
Desde Magento v2.4, se ha hecho obligatorio que instalar ElasticSearch como motor de búsquedas. Y desde la v2.4.4 han añadido soporte para OpenSearch.
En este link https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/prerequisites/search-engine/overview.html?lang=en#installation-location nos hablan de tener ElasticSearch en otro servidor, cosa que no voy a hacer, así que no seguiré exactamente los pasos. En la propia documentación de ElasticSearch también lo recomiendan, que se da por hecho que será lo único instalado en ese servidor que consuma muchos recursos ya que algunas características funcionan de esta manera… siendo todo de pruebas, en el mismo servidor.
Aquí https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/prerequisites/search-engine/configure-nginx.html?lang=en también nos dicen cómo configurar de «forma segura» Nginx… montan un password para que solo pueda usarse el motor de búsquedas desde este servidor y con ese password, montando un proxy, etc. Demasiado me parece por ahora así que no lo haré tampoco.
NOTA: el tema del riesgo en seguridad, por lo que he leído, tampoco es un riesgo si lo tenemos en el mismo servidor porque ElasticSearch escucha en 9200 del loopback (localhost)… ahora, si lo usamos en servidores diferentes, cualquiera con acceso a la API HTTP podría usarlo pero esto tiene fácil solución con un pequeño firewall que permita conexiones solo entre estos dos servidores y listo.
Instalar JDK
apt-get -y update
apt-get install -y openjdk-8-jdk
Al terminar la instalación me ha pedido reiniciar el server por una versión diferente del kernel.
Instalar ElasticSearch
Instalación
Aquí Magento nos redirige a la documentación oficial. Elijo las instrucciones para Ubuntu (Debian) https://www.elastic.co/guide/en/elasticsearch/reference/7.17/deb.html
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
sudo apt-get install apt-transport-https
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-7.x.list
sudo apt-get update && sudo apt-get install elasticsearch
Arrancar servicios
Al terminar la instalación, recibimos unos avisos de que el serviciono se inicia automáticamente, entiendo que esto ya detecta si estamos usando un administrador de servicios u otro (systemd o sysV)
### NOT starting on installation, please execute the following statements to configure elasticsearch service to start automatically using systemd
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch.service
### You can start elasticsearch service by executing
sudo systemctl start elasticsearch.service
De esta manera, arrancará el servicio automáticamente si se reinicia la máquina (con systemctl enable) y luego arrancamos el servicio manualmente por primera vez con systemctl start.
Podemos comprobar que tenemos el servicio activo con
service --status-all
Comprobaciones
¿Funciona el servicio? Desde la máquina donde se ha instalado el servicio:
curl -X GET 'http://localhost:9200'
Deberíamos obtener un json con información del servicio.
Configuraciones
Aquí explican la configuración de nginx recomendada para elasticsearch https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/prerequisites/search-engine/configure-nginx.html?lang=en es la forma «insegura», aunque hay otra segura no vamos a hacer porque excede lo que busco aprender ahora mismo (habla de hacer un proxy con Nginx creando un BasiAuth, etc, etc, y que sea solo este server el que pueda comunicarse con el servciio de Elastic pero vamos… ahora mismo lo veo demasiado)
NOTA: realmente no entiendo muy bien en este punto el motivo de que recomienden esto… ¿no sería más sencillo simplemente configurar el firewall para que no atienda a nada externo en el puerto 9200? He visto algunos tutoriales de Elastic que lo hacen así, pero sus motivos tendrán los de Magento
Como nociones generales de configurar ElasticSearch:
- Fichero principal de configuración: /etc/elasticsearch/elasticsearch.yml, donde podremos cambiar:
- definir nombre del Cluster y del Node
- añadir atributos al Node
- definir Paths (directorio donde se guarda la información /var/lib/elasticsearch y directorio de los logs /var/logs/elasticsearch)
- exponer una IP concreta para usar en conexiones remoto
- definir puerto y host
Composer
Instalación
Seguimos las instrucciones de https://getcomposer.org/download/ para instalar la versión 2.2 que es la que tenemos como requisito.
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '55ce33d7678c5a611085589f1f3ddf8b3c52d662cd01d4ba75c0ee0459970c2200a51f492d557530c71c15d8dba01eae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php --2.2
php -r "unlink('composer-setup.php');"
sudo mv composer.phar /usr/local/bin/composer
Con la útlima línea hacemos que el comando composer esté disponible en nuesto PATH.
Redis
Como punto de partida tenemos este link https://experienceleague.adobe.com/docs/commerce-operations/configuration-guide/cache/redis/config-redis.html?lang=en
Instalación
Para la instalación seguiremos la documentación oficial en este link https://redis.io/docs/getting-started/installation/install-redis-on-linux/
curl -fsSL https://packages.redis.io/gpg | sudo gpg --dearmor -o /usr/share/keyrings/redis-archive-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/redis-archive-keyring.gpg] https://packages.redis.io/deb $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/redis.list
sudo apt-get update
# comento esta línea porque me falló, explico más abajo
# sudo apt-get install redis=6:6.2.8-1rl1~jammy1
Bueno… pues no funciona. La versión la saco haciendo sudo list -a redis. Me dice que necesita la versión de redis-server que vaya con lo que quiero (¿no me resuelve automáticamente las dependencias? Raro…)
Pues al tirar un sudo apt-get install redis-server=6:6.2.8-1rl1~jammy1 me vuelve a poner lo mismo pero del paquete redis-tools.
Finalmente, la parte de instalación quedaría así, yendo manualmente con cada dependencia:
sudo apt-get install redis-tools=6:6.2.8-1rl1~jammy1
sudo apt-get install redis-server=6:6.2.8-1rl1~jammy1
sudo apt-get install redis=6:6.2.8-1rl1~jammy1
Habrá una forma más elegante SEGURO, pero oye… Hago lo que puedo, y ha funcionado que es lo importante.
Configuración
En este link que Magento nos facilita https://www.digitalocean.com/community/tutorials/how-to-install-and-secure-redis-on-ubuntu-22-04 destaco esto:
- Principal archivo de configuración: /etc/redis/redis.conf
- por defecto se conecta al host 127.0.0.1 en el puerto 6379
- Nos dice que cambiemos la directiva supervised de no a systemd porque estamos usando ubuntu. Pero como veo que por defecto pone auto como valor, lo dejo así.
Para comprobar que funciona:
redis-cli ping
Nos recomiendan:
- activar save para las RDB (Redis Database Backup). No estoy muy seguro de esta parte, en teoría está activado
- activar lo siguiente:
- lazyfree-lazy-eviction yes
- lazyfree-lazy-expire yes
- lazyfree-lazy-server-del yes
- replica-lazy-flush yes
- lazyfree-lazy-user-del yes
Magento
Composer packages
Lo vamos a instalar por Composer siguiendo este link https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/composer.html?lang=en
Nos sacamos las claves (username y password de repo.magento.com) como indican: en https://experienceleague.adobe.com/docs/commerce-operations/installation-guide/prerequisites/authentication-keys.html?lang=en
composer create-project --repository-url=https://repo.magento.com/ magento/project-community-edition=2.4.5
# nos pide username y password de repo.magento.com
Permisos correctos
find var generated vendor pub/static pub/media app/etc -type f -exec chmod g+w {} +
find var generated vendor pub/static pub/media app/etc -type d -exec chmod g+ws {} +
chown -R :www-data . # Ubuntu
chmod u+x bin/magento
Instalación
Finalmente usamos el comando que nos da Magento y ponemos nuestros datos
php bin/magento setup:install \
--base-url=https://midominio.com \
--db-host=localhost \
--db-name=magento \
--db-user=magento \
--db-password=magento \
--admin-firstname=admin \
--admin-lastname=admin \
--admin-email=admin@admin.com \
--admin-user=admin \
--admin-password=admin123 \
--backend-frontname="admin" \
--language=en_US \
--currency=EUR \
--timezone=Europe/Madrid \
--use-rewrites=1 \
--search-engine=elasticsearch7 \
--elasticsearch-host=localhost \
--elasticsearch-port=9200 \
--elasticsearch-index-prefix=magento2 \
--elasticsearch-timeout=15
Con lo cual debería tener mi Magento 2.4.5 instalado en https://midominio.com/admin, user: admin, password: admin123 (muy seguro todo).
Como paso final (porque lo he ejecutado con user root… muy listo yo, cosa que puede ocurrir): sudo chown -R www-data:www-data .
Y….. !!!! nunca me había producido tanto gozo ver la home de la Luma 🙂
Pero si te das cuenta, no hemos configurado Redis… Hagámoslo. Desconozco ahora mismo si con el magento setup:install y sus 300 argumentos habrá alguno que ya lo configure, así que lo hacemos a posteriori y nos quedamos tan tranquilos.
Configuración de cachés
Como nos lo explican aquí https://experienceleague.adobe.com/docs/commerce-operations/configuration-guide/cache/redis/redis-pg-cache.html y aquí https://experienceleague.adobe.com/docs/commerce-operations/configuration-guide/cache/redis/redis-session.html
Caché predeterminado en Redis
php bin/magento setup:config:set --cache-backend=redis --cache-backend-redis-server=127.0.0.1 --cache-backend-redis-db=0
- server es localhost
- la db usada de las 16 disponibles por defecto es la 0
- resto de opciones por defecto
Caché de páginas en Redis
php bin/magento setup:config:set --page-cache=redis --page-cache-redis-server=127.0.0.1 --page-cache-redis-db=1
- server es localhost
- la db usada es la 1
- resto de opciones por defecto
Cache de sesión en Redis
php bin/magento setup:config:set --session-save=redis --session-save-redis-host=127.0.0.1 --session-save-redis-log-level=4 --session-save-redis-db=2
- server es localhost
- la db usada es la 2
- nivel de logs de redis es 4 (deja fuera los niveles notice, info y debug)
- resto de opciones por defecto
Y el admin tambíen funciona así que me voy a dormir contento jeje