Projekty, na ktorých pracujem, sú často multi-store inštalácie. Keď sa mi už Magento podarilo rozbehať cez Docker, práve toto bola ďalšia výzva, ako z toho spraviť multi-store. Nebolo to až také jednoduché, ako sa môže na prvý pohľad zdať. Podarilo sa mi to ale po pár dňoch Googlenia a konverzácii s ChatGPT vyriešiť. Zostavil som teda článok s mojimi postrehmi a praktickým návodom, ako na to.
Predpokladom je, aby si mal rozbehaný Magento shop cez Docker. V tomto článku som napísal postup. Predtým, než sa pustíš do ďalšej práce, si naštartuj kontajnery cez bin/start.
Administrácia
Začneme v administrácii. Choď do Stores -> Settings -> All Stores a vytvor nový store. Vo väčšine prípadov tvorím nový store na úrovni „website“, pretože chcem mať k dispozícii samostatný katalóg a zľavové kupóny. Takže som vytvoril nový website, store a store view. Dôležité je, aby si si zapamätal code pre tento nový website. Budeme ho neskôr potrebovať pri konfigurácii nginx.
Potom prejdi do Stores -> Settings -> Configuration -> General -> Web, prepni si hore v dropdowne scope na nový website a zmeň Base url (unsecure aj secure).
Ak potrebuješ pre nový website nakonfigurovať inú tému, urobíš tak v Content -> Design -> Configuration. Ak náhodou v tabuľke nemáš svoj novovytvorený store, skús spustiť z príkazového riadka
bin/magento indexer:reindex
a po refreshi by sa mal v tabuľke objaviť.
Konfigurácia nginx
Teraz potrebujeme spraviť pomerne dosť zmien v nastavení nginx. Najprv choď na Github repozitár do https://github.com/markshust/docker-magento/tree/master/images/nginx a nájdi verziu nginx imagu, ktorý používaš. Ten nájdeš v compose.yaml, pod sekciou app vo svojom projekte, ktorý si predtým rozbehal cez Docker.
Prejdi potom na Githube do adresára s príslušnou verziou, do conf a bude ťa zaujímať default.conf. To je základná konfigurácia, ktorú budeme dopĺňať.
Najprv ale otvor samotný compose.yaml a nahraď pôvodný image, napr.
image: markoshust/magento-nginx:1.24-0
riadkom
build: images/nginx
Týmto zadefinuješ, že namiesto pôvodného vybuildovaného imagu, bude docker používať na zostavenie containeru tvoj vlastný image z podadresára images/nginx, ktorý o chvíľu zostavíme.
Vytvor teda podadresár images/nginx v hlavnom adresári tvojho projektu (tam, kde sú aj ostatné podadresáre, ako bin a src). Do tohto nového adresára vytvor súbor Dockerfile (bez koncovky). Toto je súbor, kde definujeme náš nový image. Tento súbor je veľmi jednoduchý. Vložíme tam len 2 riadky:
FROM markoshust/magento-nginx:1.24-0 # toto je base image, z ktorého vychádzame
COPY ./conf/default.conf /etc/nginx/conf.d/ # tu prepíšeme pôvodný default.conf novým, ktorý o chvíľu vytvoríme.
Do adresára images/nginx teraz vytvoríme ďalší podadresár s názvom conf a do neho súbor default.conf. Obsah tohto súboru zoberieme z linky, ktorú sme pred chvíľou našli na Githube, čiže napr. https://github.com/markshust/docker-magento/blob/master/images/nginx/1.24/conf/default.conf.
V súbore urobíme pár zmien.
Medzi sekcie upstream a server vložíme novú sekciu, kde zadefinujeme, akú hodnotu bude mať premenná $MAGE_RUN_CODE pre rôzne domény. Čiže napr.
map $http_host $MAGE_RUN_CODE {
default website_german;
store2.com website_austrian;
}
kde website_german je code na úrovni website pre defaultný store (ďalej doména store1.com) a website_austrian sme vytvorili pred chvíľou v Stores -> Settings -> All Stores (ďalej doména store2.com).
Do nasledujúcej sekcie server doplň riadok, kde definuješ obe domény, čiže bude vyzerať nejak takto
server {
listen 8000;
server_name store1.com store2.com;
return 301 https://$host$request_uri;
}
Toto slúži na presmerovanie z nezabezpečenej URL na https. Ďalej potrebujeme definovať toľko sekcií server, koľko storov (domén) máme v backende. Na tomto príklade definujem 2 domény. Obsah skopíruj z pôvodného súboru na Githube a celá sekcia, bude teda vyzerať nejako takto
server {
listen [::]:8443 ssl http2;
listen 8443 ssl http2;
server_name store1.com;
ssl_certificate /etc/nginx/certs/store1_com.crt;
ssl_certificate_key /etc/nginx/certs/store1_com.key;
set $MAGE_ROOT /var/www/html;
set $MAGE_RUN_TYPE website;
fastcgi_buffer_size 64k;
fastcgi_buffers 8 128k;
client_max_body_size 100M;
location /livereload.js {
proxy_set_header Host $host;
proxy_pass http://phpfpm:35729/livereload.js;
}
location /livereload {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://phpfpm:35729/livereload;
}
include /var/www/html/nginx[.]conf;
}
server {
listen [::]:8443 ssl http2;
listen 8443 ssl http2;
server_name store2.com;
ssl_certificate /etc/nginx/certs/store2_com.crt;
ssl_certificate_key /etc/nginx/certs/store2_com.key;
set $MAGE_ROOT /var/www/html;
set $MAGE_RUN_TYPE website;
fastcgi_buffer_size 64k;
fastcgi_buffers 8 128k;
client_max_body_size 100M;
location /livereload.js {
proxy_set_header Host $host;
proxy_pass http://phpfpm:35729/livereload.js;
}
location /livereload {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_pass http://phpfpm:35729/livereload;
}
include /var/www/html/nginx[.]conf;
}
v oboch sekciách je dôležité, aby si z pôvodného riadku
listen [::]:8443 ssl http2 ipv6only=on;
vyhodil
ipv6only=on
Ináč mi kontajner vyhadzoval chybu.
Ďalej som tam upravoval cestu k SSL certifikátom, ktoré o chvíľu vytvoríme. Každá doména potrebuje mať svoje vlastné certifikáty. Tiež som zadefinoval premennú $MAGE_RUN_TYPE na hodnotu „website“, keďže som sa rozhodol, že doména bude smerovať práve na scope website. Druhá možnosť by bola definovať tam „store“ a v takom prípade musíš zmeniť aj sekciu map, kde premenná $MAGE_RUN_CODE bude obsahovať code na úrovni store view.
Posledný konfiguračný súbor, ktorý musíme upraviť bude samotný nginx.conf. Naša docker inštalácia obsahuje v compose.dev.yaml definíciu volumes, ktorá synchronizuje obsah src/nginx.conf.sample do kontajnerového /var/www/html/nginx.conf. Je to štandardný nginx.conf file tak, ako ho odporúča Magento.
My najprv v adresári „src“ vytvoríme nový súbor s názvom nginx.conf, do ktorého skopíruj obsah nginx.conf.sample. Ďalej v compose.dev.yaml nastav, aby sa synchronizoval tento novovytvorený nginx.conf, čiže riadok bude vyzerať
./src/nginx.conf:/var/www/html/nginx.conf:cached
V novom súbore nginx.conf scrollni úplne dole, kde máš definíciu
location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check).php$
a pred posledný include pridaj tieto dva parametre, ktoré sme pred chvíľou definovali
fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE;
fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE;
Celá sekcia teda bude vyzerať približne takto
# PHP entry point for main application
location ~ ^/(index|get|static|errors/report|errors/404|errors/503|health_check)\.php$ {
try_files $uri =404;
fastcgi_pass fastcgi_backend;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
fastcgi_param PHP_FLAG "session.auto_start=off \n suhosin.session.cryptua=off";
fastcgi_param PHP_VALUE "memory_limit=756M \n max_execution_time=18000";
fastcgi_read_timeout 600s;
fastcgi_connect_timeout 600s;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param MAGE_RUN_TYPE $MAGE_RUN_TYPE;
fastcgi_param MAGE_RUN_CODE $MAGE_RUN_CODE;
include fastcgi_params;
}
Ak ešte nemáš v /etc/hosts definovanú doménu pre store2.com, teraz tak sprav, podobne ako tomu máš pre store1.com.
SSL certifikáty
Posledná vec na to, aby nám všetko fungovalo v poriadku, je vygenerovať SSL certifikáty pre obe domény. Normálne na toto existuje skript bin/setup-ssl, ktorý však v čase písania tohto článku nefungoval pre viaceré domény. Vždy vygeneroval certifikát iba jednu doménu a prepísal nginx.key a nginx.crt na hodnotu pre danú doménu.
Podľa diskusie na túto tému (https://github.com/markshust/docker-magento/issues/1172), kde mimochodom nájdeš aj môj komentár, kde som skopíroval celý default.conf, som vytvoril nový bash skript, ktorý ide do bin/setup-ssl-new. Vytvor teda tento súbor a skopíruj do neho obsah
#!/usr/bin/env bash
[ $# -eq 0 ] && echo "Please specify at least one domain (ex. mydomain.test)" && exit 1
# Generate certificate authority if not already setup
if ! bin/docker-compose exec -T -u root app cat /root/.local/share/mkcert/rootCA.pem | grep -q 'BEGIN CERTIFICATE'; then
bin/setup-ssl-ca
fi
for DOMAIN in "$@"; do
# Generate a unique file prefix based on the domain name
DOMAIN_WITHOUT_PORT=$(echo "$DOMAIN" | cut -d ':' -f1)
CERT_PREFIX=$(echo "$DOMAIN_WITHOUT_PORT" | tr '.' '_')
# Generate the certificate for the specified domain
bin/docker-compose exec -T -u root app mkcert -key-file "${CERT_PREFIX}.key" -cert-file "${CERT_PREFIX}.crt" "$DOMAIN_WITHOUT_PORT"
# Check if the certificates were created successfully
if bin/docker-compose exec -T -u root app test -f "${CERT_PREFIX}.key" && bin/docker-compose exec -T -u root app test -f "${CERT_PREFIX}.crt"; then
echo "Moving key and cert for $DOMAIN to /etc/nginx/certs/..."
bin/docker-compose exec -T -u root app chown app:app "${CERT_PREFIX}.key" "${CERT_PREFIX}.crt"
bin/docker-compose exec -T -u root app mv "${CERT_PREFIX}.key" "${CERT_PREFIX}.crt" /etc/nginx/certs/
else
echo "Error: Certificates for $DOMAIN were not created."
fi
done
# Restart nginx to apply the updates
echo "Restarting containers to apply updates..."
bin/restart
Spustíš ho potom cez
bin/setup-ssl-new store1.com store2.com
Skript iteruje cez všetky domény a vytvorí v kontajneri dvojicu certifikátov store1_com.crt a store1_com.key pre doménu store1.com a obdobne store2_com.crt a store2_com.key pre doménu store2.com.
Po spustení toho skriptu, by sa mali aj reštartnúť kontajnery, aby sa aplikovali nové zmeny. Tiež by sa mal vybuildovať app kontajner nanovo, keďže sme zmenili jeho image v compose.yaml.
Keby si v budúcnosti robil nejaké zmeny v Dockerfile, treba spustiť znova vybuildovanie imagu cez
docker compose build
Verím, že na základe tohto návodu sa ti úspešne podarilo nakonfigurovať multi-store inštaláciu Magenta z pôvodnej single-store, ktorú si mal nainštalovanú predtým.